Dubbo,SpringCloud,ServiceMesh Dear 丶 2023-07-06 13:23 8阅读 0赞 # 微服务 # 微服务(Microservices)是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。 **微服务的优点:** 1.降低复杂度 将原来偶合在一起的复杂业务拆分为单个服务,规避了原本复杂度无止境的积累。每一个微服务专注于单一功能。 2.可独立部署 由于微服务具备独立的运行进程,所以每个微服务可以独立部署。当业务迭代时只需要发布相关服务的迭代即可,降低了测试的工作量同时也降低了服务发布的风险。 3.容错 在微服务架构下,当某一组件发生故障时,故障会被隔离在单个服务中。 通过限流、熔断等方式降低错误导致的危害,保障核心业务正常运行。 4.扩展 单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。 **微服务的缺点:** 1.团队沟通的过载 微服务架构降低了团队管理的难度,但是确不能降低团队沟通的需求。 2、正式文档的过载 每一个独立的运行部件需要持续维护其规格和接口文档,这些文档是其它团队使用这些部件的必要条件。 3、不一致性 我们可以为每一个组件选择不同的技术栈。这导致了不一致的应用设计和架构,而这会在更长期的运维期间增加系统维护成本。 4、DevOps的复杂度 我们需要拥有一支成熟的DevOps团队去处理微服务架构的应用的复杂性。 5、资源使用 运行这些微服务架构的应用的初始投资会比较大。 6、网络通信开销 分布式系统的产生的网络开销比单机应用多很多。需要更加可靠和快速的网络连接。 7、编码和解码 这个容易理解,也会产生性能问题。 8、网络安全 通过网络进行通信的系统更容易产生安全缺陷。 9、测试 测试微服务架构的应用绝对比单体应用难很多。 10、产品监控 监控微服务架构应用的成本会更高,很难获得合适的工具,需自研。 # # # Dubbo # Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。简单的说,Dubbo 就是个服务框架,说白了就是个远程服务调用的分布式框架。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70][] **模块注解**: Provider: 暴露服务的服务提供方。 Consumer: 调用远程服务的服务消费方。 Registry: 服务注册与发现的注册中心。 Monitor: 统计服务的调用次调和调用时间的监控中心。 Container: 服务运行容器。 **流程详解**: 0.服务容器负责启动,加载,运行服务提供者(Standalone 容器)。 1.服务提供者在启动时,向注册中心注册自己提供的服务(Zookeeper/Redis)。 2.服务消费者在启动时,向注册中心订阅自己所需的服务。 3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。 4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。 5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心(根据数据可以动态调整权重)。 **Dubbo****优点** 1.Dubbo 支持 RPC 调用,服务之间的调用性能会很好。 2.支持多种序列化协议,如 Hessian、HTTP、WebService。 3.Dobbo Admin后台管理功能强大,提供了路由规则、动态配置、访问控制、权重调节、均衡负载等功能。 4.在国内影响力比较大,中文社区文档较为全面。 5.阿里最近重启维护。 **Dubbo****问题** 1.注册中心严重依赖第三方组件(zookeeper 或者 redis),当这些组件出现问题时,服务调用很快就会中断。 2.Dubbo 只支持 RPC 调用。使得服务提供方(抽象接口)与调用方在代码上产生了强依赖,服务提供者需要不断将包含抽象接口的 jar 包打包出来供消费者使用。一旦打包出现问题,就会导致服务调用出错,并且以后发布部署会成很大问题(太强的依赖关系)。 3.Dubbo 只是实现了服务治理,其他微服务框架并未包含,如果需要使用,需要结合第三方框架实现(比如分布式配置用淘宝的 Diamond、服务跟踪用京东的 Hydra,但使用相对麻烦些),开发成本较高,且风险较大。 4.社区更新不及时(虽然最近在疯狂更新),但也难免阿里以后又不更新了,就尴尬了。 5.主要是国内公司使用,但阿里内部使用 HSF,相对于 Spring Cloud,企业应用会差一些。 # Spring Cloud # Spring Cloud 基于 Spring Boot,为微服务体系开发中的架构问题,提供了一整套的解决方案——服务注册与发现,服务消费,服务保护与熔断,网关,分布式调用追踪,分布式配置管理等。 **Spring Cloud****组件架构** ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 1][] 流程: 1.请求统一通过 API 网关(Zuul)来访问内部服务。 2.网关接收到请求后,从注册中心(Eureka)获取可用服务。 3.由 Ribbon 进行均衡负载后,分发到后端具体实例。 4.微服务之间通过 Feign 进行通信处理业务。 5.Hystrix 负责处理服务超时熔断。 6.Turbine 监控服务间的调用和熔断相关指标。 **Spring Cloud****优点** 1.有强大的 Spring 社区、Netflix 等公司支持,并且开源社区贡献非常活跃。 2.标准化的将微服务的成熟产品和框架结合一起,Spring Cloud 提供整套的微服务解决方案,开发成本较低,且风险较小。 3.基于 Spring Boot,具有简单配置、快速开发、轻松部署、方便测试的特点。 4.支持 REST 服务调用,相比于 RPC,更加轻量化和灵活(服务之间只依赖一纸契约,不存在代码级别的强依赖),有利于跨语言服务的实现,以及服务的发布部署。另外,结合 Swagger,也使得服务的文档一体化。 5.提供了 Docker 及 Kubernetes 微服务编排支持。 6.国内外企业应用非常多,经受了大公司的应用考验(比如 Netfilx 公司),以及强大的开源社区支持。 **Spring Cloud****问题** 1.支持 REST 服务调用,可能因为接口定义过轻,导致定义文档与实际实现不一致导致服务集成时的问题(可以使用统一文档和版本管理解决,比如 Swagger)。 2.另外,REST 服务调用性能会比 RPC 低一些(但也不是强绑定) 3.Spring Cloud 整合了大量组件,相关文档比较复杂,需要针对性的进行阅读。 # Dubbo、SpringCloud性能对比 # Spring Cloud 抛弃了 Dubbo 的 RPC 通信,采用的是基于 HTTP 的 REST 方式。严格来说,这两种方式各有优劣。虽然从一定程度上来说,后者牺牲了服务调用的性能,但也避免了上面提到的原生 RPC 带来的问题。而且 REST 相比 RPC 更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更加合适。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 2][] # Dubbo、SpringCloud工具框架对比 # Dubbo 专注 RPC 和服务治理,Spring Cloud 则是一个微服务架构生态。 ![https://images2018.cnblogs.com/blog/435188/201804/435188-20180412214125747-2064544666.png][https_images2018.cnblogs.com_blog_435188_201804_435188-20180412214125747-2064544666.png] # ZooKeeper、Eureka注册中心对比 # 鉴于服务发现对服务化架构的重要性,Dubbo 实践通常以 ZooKeeper 为注册中心(Dubbo 原生支持的 Redis 方案需要服务器时间同步,且性能消耗过大)。针对分布式领域著名的 CAP 理论(C——数据一致性,A——服务可用性,P——服务对网络分区故障的容错性),Zookeeper 保证的是 CP ,但对于服务发现而言,可用性比数据一致性更加重要,AP 胜过 CP,而 Eureka 设计则遵循 AP 原则。 Spring Cloud 支持 Consul(CA)和 Zookeeper,但不推荐使用。 # 社区活跃度对比 # 我们选择一个开源框架,社区的活跃度是我们极为关注的一个要点。社区越活跃,解决问题的速度越快,框架也会越来越完善,不然当我们碰到问题,就不得不自己解决。而对于团队来说,也就意味着我们不得不自己去维护框架的源码,这对于团队来说也将会是一个很大的负担。 Dubbo:[https://github.com/dubbo][https_github.com_dubbo] 更新时间为:2019.4.24 活跃度低![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 3][] Spring Cloud:[https://github.com/spring-cloud][https_github.com_spring-cloud] 更新时间为:6分钟前 活跃度很高。![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 4][] # 选型参考 # **Dubbo** **和 Spring Cloud** **比喻** 使用 Dubbo 构建的微服务架构就像组装电脑,各环节我们的选择自由度很高,但是最终结果很有可能因为一条内存质量不行就点不亮了,总是让人不怎么放心,但是如果你是一名高手,那这些都不是问题;而 Spring Cloud 就像品牌机,在 Spring Source 的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性,但是如果要在使用非原装组件外的东西,就需要对其基础有足够的了解。 **网易考拉的选型参考** 当前开源上可选用的微服务框架主要有 Dubbo、Spring Cloud 等,鉴于 Dubbo 完备的功能和文档且在国内被众多大型互联网公司选用,考拉自然也选择了 Dubbo 作为服务化的基础框架。其实相比于 Dubbo,Spring Cloud 可以说是一个更完备的微服务解决方案,它从功能性上是 Dubbo 的一个超集,个人认为从选型上对于一些中小型企业 Spring Cloud 可能是一个更好的选择。 提起 Spring Cloud,一些开发的第一印象是 HTTP + JSON 的 REST 通信,性能上难堪重用,其实这也是一种误读。微服务选型要评估以下几点:内部是否存在异构系统集成的问题;备选框架功能特性是否满足需求;HTTP 协议的通信对于应用的负载量会否真正成为瓶颈点(Spring Cloud 也并不是和 HTTP + JSON 强制绑定的,如有必要 Thrift、ProtoBuf 等高效的 RPC、序列化协议同样可以作为替代方案);社区活跃度、团队技术储备等。作为已经没有团队持续维护的开源项目,选择 Dubbo 框架内部就必须要组建一个维护团队,先不论你要准备要集成多少功能做多少改造,作为一个支撑所有工程正常运转的基础组件,问题的及时响应与解答、重大缺陷的及时修复能力就已足够重要。 # Service Mesh # ServiceMesh(服务网格) 概念在社区里头非常火,有人提出 2018 年是 ServiceMesh 年,还有人提出 ServiceMesh 是下一代的微服务架构基础。那么到底什么是 ServiceMesh?它的诞生是为了解决什么问题?企业是否适合引入 ServiceMesh? **微服务架构的核心技术问题** 在业务规模化和研发效能提升等因素的驱动下,从单块应用向微服务架构的转型 (如下图所示),已经成为很多企业 (尤其是互联网企业) 数字化转型的趋势。 ![https://img2018.cnblogs.com/blog/21899/201812/21899-20181212090720493-1458017369.png][https_img2018.cnblogs.com_blog_21899_201812_21899-20181212090720493-1458017369.png] 在微服务模式下,企业内部服务少则几个到几十个,多则上百个,每个服务一般都以集群方式部署,这时自然产生两个问题 (如下图所示): ![https://img2018.cnblogs.com/blog/21899/201812/21899-20181212090753027-1069166921.png][https_img2018.cnblogs.com_blog_21899_201812_21899-20181212090753027-1069166921.png] 一、服务发现: 服务的消费方 (Consumer) 如何发现服务的提供方 (Provider)? 二、负载均衡: 服务的消费方如何以某种负载均衡策略访问集群中的服务提供方实例? 作为架构师,如果你理解了这两个问题,也就理解了微服务架构在技术上最核心问题。 **三种服务发现模式** 服务发现和负载均衡并不是新问题,业界其实已经探索和总结出一些常用的模式,这些模式的核心其实是代理 (Proxy,如下图所以),以及代理在架构中所处的位置。 ![https://img2018.cnblogs.com/blog/21899/201812/21899-20181212091031767-1868392272.png][https_img2018.cnblogs.com_blog_21899_201812_21899-20181212091031767-1868392272.png] 在服务消费方和服务提供方之间增加一层代理,由代理负责服务发现和负载均衡功能,消费方通过代理间接访问目标服务。根据代理在架构上所处的位置不同,当前业界主要有三种不同的服务发现模式: **模式一**:传统集中式代理 ![https://img2018.cnblogs.com/blog/21899/201812/21899-20181212091147917-203055964.png][https_img2018.cnblogs.com_blog_21899_201812_21899-20181212091147917-203055964.png] 这是最简单和传统做法,在服务消费者和生产者之间,代理作为独立一层集中部署,由独立团队 (一般是运维或框架) 负责治理和运维。常用的集中式代理有硬件负载均衡器 (如F5),或者软件负载均衡器 (如 Nginx),F5(4 层负载)+Nginx(7 层负载) 这种软硬结合两层代理也是业内常见做法,兼顾配置的灵活性 (Nginx 比 F5 易于配置)。 这种方式通常在 DNS 域名服务器的配合下实现服务发现,服务注册 (建立服务域名和 IP 地址之间的映射关系) 一般由运维人员在代理上手工配置,服务消费方仅依赖服务域名,这个域名指向代理,由代理解析目标地址并做负载均衡和调用。 国外知名电商网站 eBay,虽然体量巨大,但其内部的服务发现机制仍然是基于这种传统的集中代理模式,国内公司如携程,也是采用这种模式。 **模式二**:客户端嵌入式代理 ![https://img2018.cnblogs.com/blog/21899/201812/21899-20181212091222199-336866489.png][https_img2018.cnblogs.com_blog_21899_201812_21899-20181212091222199-336866489.png] 这是很多互联网公司比较流行的一种做法,代理 (包括服务发现和负载均衡逻辑) 以客户库的形式嵌入在应用程序中。这种模式一般需要独立的服务注册中心组件配合,服务启动时自动注册到注册中心并定期报心跳,客户端代理则发现服务并做负载均衡。Netflix 开源的 Eureka(注册中心)和 Ribbon(客户端代理)是这种模式的典型案例,国内阿里开源的 Dubbo 也是采用这种模式。 **模式三**:主机独立进程代理 这种做法是上面两种模式的一个折中,代理既不是独立集中部署,也不嵌入在客户应用程序中,而是作为独立进程部署在每一个主机上,一个主机上的多个消费者应用可以共用这个代理,实现服务发现和负载均衡,如下图所示。这个模式一般也需要独立的服务注册中心组件配合,作用同模式二。 ![https://img2018.cnblogs.com/blog/21899/201812/21899-20181212091309512-519378906.png][https_img2018.cnblogs.com_blog_21899_201812_21899-20181212091309512-519378906.png] 阿里、微博、摩拜、唯品会等公司都在积极探索Service Mesh的架构模式,只是在实践中一般具备一定开发能力的公司都会选择基于Istio进行二次开发,如目前阿里开源的SOFAMesh/SOFAMosn两个项目。 **Service Mesh****(服务网格)** Service Mesh又称为服务网格,本质上就是我们前面介绍过的**模式三**。之所为称之为服务网格是因为按照模式三的结构,每个主机上同时运行了业务逻辑代码和代理,此时这个代理被形象地称之为SideCar(业务代码进程相当于主驾驶,共享一个代理相当于边车),服务之间通过SideCar发现和调用目标服务,从而形成服务之间的一种网络状依赖关系,然后通过独立部署的一种称之为控制平面(ControlPlane)的独立组件来集中配置这种依赖调用关系以及进行路由流量调拨等操作,如果此时我们把主机和业务逻辑从视觉图上剥离,就会出现一种网络状的架构,服务网格由此得名。 ![https://img2018.cnblogs.com/blog/21899/201812/21899-20181212092501971-882456460.png][https_img2018.cnblogs.com_blog_21899_201812_21899-20181212092501971-882456460.png] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 5][] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 6][] 在新一代的Service Mesh架构中服务消费方和提供方的主机(或容器)两边都会部署代理SideCar,此时SideCar与服务所在的主机又称之为数据平面(DataPlane),与我们前面说到的用于依赖关系配置和流量调拨操作的控制平面相对应。 **Istio** 通过上述的内容,我们从概念上应该是大概理解了什么是Service Mesh。而具体要落地Service Mesh只有概念是远远不够的,相反,如果没有一种可落地执行的开源框架,这个概念也不会这么快被大家所接受。Istio就是目前受Google/IBM 等大厂支持和推进的一个 ServiceMesh开源框架组合。它解决了开发人员和运维人员在整体应用程序向分布式微服务体系结构过渡时所面临的挑战。我们知道无论是基于SpringCloud的微服务架构体系还是目前我们说到的Service Mesh,随着微服务规模的增长会带来很多的复杂性,如服务发现、负载均衡、故障恢复、监控,甚至A/B测试、访问控制等。而要对涉及这些问题的微服务架构体系进行管理,如果没有成熟的组件的话,就会需要耗费很多的精力去开发一些运维工具,而这个成本是非常高的。而Istio则提供了一个完整的解决方案来满足微服务应用程序的各种需求。下图是Istio官网(https://istio.io)所展示的关于Istio的一张架构图: ![https://img2018.cnblogs.com/blog/21899/201812/21899-20181212092701571-1505585761.png][https_img2018.cnblogs.com_blog_21899_201812_21899-20181212092701571-1505585761.png] 在这张架构图中Istio服务网格在逻辑上还是分为数据平面和控制平面。数据平面中的SideCar代理是由一款叫做Envoy的组件来承担的,它是一款用C++开发的高性能代理,用于协调服务网格中所有服务的入站和出站流量。 **Envoy****提供了很多内在的特性如:** **动态服务发现** **负载均衡** **TLS****终止** **HTTP/2****和****gRPC****代理** **熔断器** **健康检查** **基于百分比的流量分割** **故障注入** 丰富的指标在Istio控制平面中的各个组件的作用如下: Mixer:负责收集代理上采集的度量数据,进行集中监控; Pilot:主要为SideCar提供服务发现、智能路由(如A/B测试)、弹性(超时、重试、断路器)的流量管理功能; Citadel:负责安全控制数据的管理和下发; 从上面的特性上看实际上Envoy已经提供了很完备的SideCar的功能,只是由于其采用的是C++开发的,目前在国内的落地实践中会有不同的取舍和选择,如蚂蚁金服内部在实践的过程中就没有使用Istio默认集成的Envoy,而是用 Golang 开发了新的 Sidecar,已经开源的SOFAMosn,来替代 Envoy。 以上就是关于Istio及其组件的一些介绍,具体如何使用Istio进行服务开发及安装操作,大家可以看看Istio的官网,另外需要强调的是kubernetes是目前 Isito 主力支持的容器云环境。 **Service Mesh****的优势** 事实上Service Mesh这种架构模式并不新鲜,很早就有公司进行过尝试,之所以最近又火起来的原因,主要还是因为模式一、模式二的确有一些固有的缺陷,模式一相对比较重,有单点问题和性能问题。而模式二则有客户端复杂,支持多语言困难,路由、熔断、限流等服务操作无法集中治理的问题。而Service Mesh则正好弥补了二者的不足,它是纯分布式的,没有单点的问题,性能也比较优秀并且与开发语言无关,还可以集中进行治理。此外,随着微服务化、多语言和容器化的发展趋势,很多公司也迫切需要一种轻量级的服务发现机制,加上一些大厂如Google/IBM的助推(如kubernetes与Docker的容器之争),正好Service Mesh迎合了这种趋势,所以才有今天火热的局面。 # 参数文献 # 1.微服务架构基础之Service Mesh https://www.cnblogs.com/tianyamoon/p/10106587.html 2.Java微服务框架选型(Dubbo 和 Spring Cloud?) https://www.cnblogs.com/xishuai/archive/2018/04/13/dubbo-and-spring-cloud.html 3.Eureka和ZooKeeper的区别 https://blog.csdn.net/java\_xth/article/details/82621776 4.比较spring cloud和dubbo,各自的优缺点是什么 https://blog.csdn.net/u010664947/article/details/80007767 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70]: https://img-blog.csdnimg.cn/20200219130330538.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ==,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 1]: https://img-blog.csdnimg.cn/20200219130330523.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ==,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 2]: https://img-blog.csdnimg.cn/20200219130330577.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ==,size_16,color_FFFFFF,t_70 [https_images2018.cnblogs.com_blog_435188_201804_435188-20180412214125747-2064544666.png]: https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvNDM1MTg4LzIwMTgwNC80MzUxODgtMjAxODA0MTIyMTQxMjU3NDctMjA2NDU0NDY2Ni5wbmc?x-oss-process=image/format,png [https_github.com_dubbo]: https://github.com/dubbo [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 3]: https://img-blog.csdnimg.cn/20200219130330549.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ==,size_16,color_FFFFFF,t_70 [https_github.com_spring-cloud]: https://github.com/spring-cloud [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 4]: https://img-blog.csdnimg.cn/20200219130330574.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ==,size_16,color_FFFFFF,t_70 [https_img2018.cnblogs.com_blog_21899_201812_21899-20181212090720493-1458017369.png]: https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMjE4OTkvMjAxODEyLzIxODk5LTIwMTgxMjEyMDkwNzIwNDkzLTE0NTgwMTczNjkucG5n?x-oss-process=image/format,png [https_img2018.cnblogs.com_blog_21899_201812_21899-20181212090753027-1069166921.png]: https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMjE4OTkvMjAxODEyLzIxODk5LTIwMTgxMjEyMDkwNzUzMDI3LTEwNjkxNjY5MjEucG5n?x-oss-process=image/format,png [https_img2018.cnblogs.com_blog_21899_201812_21899-20181212091031767-1868392272.png]: https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMjE4OTkvMjAxODEyLzIxODk5LTIwMTgxMjEyMDkxMDMxNzY3LTE4NjgzOTIyNzIucG5n?x-oss-process=image/format,png [https_img2018.cnblogs.com_blog_21899_201812_21899-20181212091147917-203055964.png]: https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMjE4OTkvMjAxODEyLzIxODk5LTIwMTgxMjEyMDkxMTQ3OTE3LTIwMzA1NTk2NC5wbmc?x-oss-process=image/format,png [https_img2018.cnblogs.com_blog_21899_201812_21899-20181212091222199-336866489.png]: https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMjE4OTkvMjAxODEyLzIxODk5LTIwMTgxMjEyMDkxMjIyMTk5LTMzNjg2NjQ4OS5wbmc?x-oss-process=image/format,png [https_img2018.cnblogs.com_blog_21899_201812_21899-20181212091309512-519378906.png]: https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMjE4OTkvMjAxODEyLzIxODk5LTIwMTgxMjEyMDkxMzA5NTEyLTUxOTM3ODkwNi5wbmc?x-oss-process=image/format,png [https_img2018.cnblogs.com_blog_21899_201812_21899-20181212092501971-882456460.png]: https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMjE4OTkvMjAxODEyLzIxODk5LTIwMTgxMjEyMDkyNTAxOTcxLTg4MjQ1NjQ2MC5wbmc?x-oss-process=image/format,png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 5]: https://img-blog.csdnimg.cn/20200219130330582.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ==,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ_size_16_color_FFFFFF_t_70 6]: https://img-blog.csdnimg.cn/20200219130330664.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ZvcmV2ZXJMb3ZlSGViZQ==,size_16,color_FFFFFF,t_70 [https_img2018.cnblogs.com_blog_21899_201812_21899-20181212092701571-1505585761.png]: https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMjE4OTkvMjAxODEyLzIxODk5LTIwMTgxMjEyMDkyNzAxNTcxLTE1MDU1ODU3NjEucG5n?x-oss-process=image/format,png
还没有评论,来说两句吧...