微服务(一)

3 篇文章 0 订阅

一、单体架构、SOA、微服务架构、集群与分布式
单体架构:一个归档包(例如war格式或者Jar格式)包含了应用所有功能的应用程序,我们通常称之为单体应用。架构单体应用的方法论,我们称之为单体应用架构,这是一种比较传统的架构风格。

单体架构的缺陷:
1.复杂性高
整个项目包含的模块非常多,模块的边界模糊,依赖关系不清晰,代码质量参差不齐,整个项目非常复杂。每次修改代码都心惊胆战,甚至添加一个简单的功能,或者修改一个BUG都会造成隐含的缺陷。

2.技术债务逐渐上升
随着时间推移、需求变更和人员更迭,会逐渐形成应用程序的技术债务,并且越积越多。已使用的系统设计或代码难以修改,因为应用程序的其他模块可能会以意料之外的方式使用它。

3.部署速度逐渐变慢
随着代码的增加,构建和部署的时间也会增加。而在单体应用中,每次功能的变更或缺陷的修复都会导致我们需要重新部署整个应用。全量部署的方式耗时长、影响范围大、风险高,这使得单体应用项目上线部署的频率较低,从而又导致两次发布之间会有大量功能变更和缺陷修复,出错概率较高。

4.扩展能力受限,无法按需伸缩
单体应用只能作为一个整体进行扩展,无法结合业务模块的特点进行伸缩。

5.阻碍技术创新
单体应用往往使用统一的技术平台或方案解决所有问题,团队的每个成员都必须使用相同的开发语言和架构,想要引入新的框架或技术平台非常困难。

SOA:面向服务的架构。SOA是一种粗粒度、松耦合服务架构,服务之间通过简单、精确定义接口进行通讯,不涉及底层编程接口和通讯模型。SOA可以看作是B/S模型、XML(标准通用标记语言的子集)/Web Service技术之后的自然延伸。

SOA的优缺点:
优点:敏捷性、一致性、业务流程的改进、灵活性、数据统一、运行监控、利用操作平台。

缺点:组织结构的改变、组织权力结构的改变、业务面临的新挑战、IT变得简单之前会越来越复杂、没有数据视图、监控复杂性、技术不匹配。

微服务架构:微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。

优缺点:
优点:上面的单体系统全部运行于一个进程之内,资源相互影响,添加功能可能会影响其它功能,导致维护麻烦。 而微服务一切分为不同的模块,运行于自身进程内,而且不同的服务可以使用不同的语言充分发挥优势。

缺点:引入了分布式的复杂性,如接口一致性。 不过很多问题强大的Spring Cloud都已经提供了解决方案!

集群:单机处理到达瓶颈的时候,你就把单机复制几份,这样就构成了一个“集群”。集群中每台服务器就叫做这个集群的一个“节点”,所有节点构成了一个集群。每个节点都提供相同的服务,那么这样系统的处理能力就相当于提升了好几倍(有几个节点就相当于提升了这么多倍)。使每个节点的压力都比较平均,使用负载均衡服务器。

分布式:分布式结构就是将一个完整的系统,按照业务功能,拆分成一个个独立的子系统,在分布式结构中,每个子系统就被称为“服务”。这些子系统能够独立运行在web容器中,它们之间通过RPC方式或者HTTP的Restful风格的API通信。

分布式和集群的区别
集群是个物理形态,分布式是个工作方式。

集群:同一个业务,部署在多个服务器上
分布式:一个业务分拆多个子业务,部署在不同的服务器上

微服务和SOA的区别
SOA(Service Oriented Architecture)“面向服务的架构”:他是一种设计方法,其中包含多个服务, 服务之间通过相互依赖最终提供一系列的功能。一个服务 通常以独立的形式存在与操作系统进程中。各个服务之间 通过网络调用。

微服务架构:其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。

二、主流微服务架构
Dubbo
阿里巴巴在 2011 年开源了 Dubbo 框架,虽然在 2013 年停止更新,但在 2017 月又重启维护并发布了新版本,目前已有很多的公司将自己的业务建立在 Dubbo 之上,同时阿里云也推出了企业级分布式应用服务 EDAS,为 Dubbo提供应用托管。
Dubbo采用 Zoopeeper 作为注册中心,RPC作为服务调用方式,致力于提供高性能和透明化的RPC远程服务调用方案,它与 Spring无缝集成,基于服务提供方(服务端)与服务调用方(客户端)角色构建简单模型,其优点是使用方便、学习成本低。

在这里插入图片描述
大致过程:
①服务提供方发布服务到服务注册中心。
②服务消费方从服务注册中心订阅服务。
③注册中心通知消息调用方服务巳注册。
④服务消费方调用已经注册的可用服务。
⑤监控计数。

Spring Cloud
Spring Cloud基于Spring Boot实现,使用 HTTP的RESTful 风格 API作为调用方式,它所包含的多个子项目共同构建了微服务架构体系。
在这里插入图片描述
Netflix Eureka:
Spring Cloud 的服务注册中心提供服务注册、服务发现、负载均衡等功能。
Netflix Hystrix:
当某个服务发生故障之后,则触发熔断机制(Hystrix )向服务调用方返回结果标识错误,而不是一直等待服务提供方返回结果,这样就不会使得线程因调用故障服务而被长时间占用不释放,避免了故障在分布式系统中的蔓延。
Netflix Zuul:
代理各模块提供的服务,统一暴露给第三方应用。提供动态路由、监控、弹性、全等的边缘服务。
Config Server:
分布式架构下多微服务会产生非常多的配置文件,分布式配置中心( Config Server )将所有配置文件交由 GIT或SVN 进行统一管理,避免出错。
Spring Boot:
在使用 Spring 开发时,通常需要完成 Spring 框架及其他第三方工具配置文件的编写,非常麻烦。Spring Boot 通过牺牲项目的自由度来减少配置的复杂度,约定一套规则,把这些框架都自动配置集成好,从而达到“开箱即用”。

三、Dubbo+Zookeeper
最基本的Dubbo工程由服务提供方、消费方、服务接口组成,接口工程中编写所提供服务的接口( Interface )由服务提供方实现具体业务逻辑并注册服务,消费方则基于接口工程中所规定的服务接口进行调用,各工程之间基于 Maven 管理依赖。

注册中心
Dubbo支持多种注册中心,其中 Zoopkeeper 最为可靠,并且官方也推荐使用。
Zoopkeeper是Apache Hadoop 的子项目,主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。

1.Zoopkeeper 的安装非常简单,从官网下载后解压,进入 conf 目录中把 zoo_sample cfg 重命名为zoo.cfg 便可开始配置。

tickTime=2000
initLimit=lO
syncLimit=S
dataDir=E:\\apache\\zookeeper-3.5.3-beta\\data
clientPort=2181
admin.serverPort=9090 

tick Time:
服务器之间或客户端与服务器之间维持心跳的时间间隔。

initlimit:
配置在集群中与其他 Zoopkeeper 连接最大心跳时间间隔数。

synclimit:
标识 Leader Follower 之间发送消息时请求和应答的时间长度,规定了在此期间最长不能超过多少个心跳数。

dataDir:
保存数据的目录。

clientPort:
客户端连接服务器的端口,zookeeper会监听这个端口,接受客户端的访问请求。

admin.serverPort
Jetty 服务的监听端口,默认是8080。

2.集群配置:
server.A : B:C:D ,其中A表示服务器编号,B表示该服务器的 IP 地址,C和D是两个 TCP 端口号,
分别用于仲裁和Leader 选举。
server.1: 192.169.1.22:2222:2223
server.2: 192.169.1.23:2222:2223
示例表示当前的 Zookeeper与IP为22和23的Zookeeper 组成集群,如果 IP 相同,则用于仲裁和选
举的端口号需要区分。

3.启动:
启动脚本存放在 zookeeper的bin目录中,根据你的操作系统选择。
Windows:由CMD或PowerShell 命令进入Zookeeper的bin目录中,并执行.\zkServer.cmd。
Linux:进人 Zookeeper的bin目录中,并执行zkServer.sh start。

接口工程
与之前“实现一个最简单的微服务框架”中的公共接口一样 ,这里需要新建一个 Maven 应用,并服务于服务提供方与消费方。

Maven参数

groupId: org.book.rpc.dubbo
artifactid: dubbo-api
version : 0.0.1-SNAPSHOT
packaging:jar

编写接口

public interface IHello {
public String say(String msg) ;
}

服务端:
①新建 Spring Boot 应用。
可使用Spring Boot初始化器。

groupld : org.book.rpc.dubbo
artifactld: dubbo-service
version: 0.0.1-SNAPSHOT
packaging : jar 

②在 pom.xml 文件中添加 Dubbo与接口应用的依赖。

<dependency>
	<groupid>io.dubbo.springboot</groupid>
	<artifactid>spring-boot-starter-dubbo</artifactid>
	<version>1.0.0</version>
</dependency>
<dependency>
	<groupid>org.book.rpc.dubbo</groupid>
	<artifactid>dubbo-api</artifactid>
	<version>0.0.1-SNAPSHOT</version>
</dependency>

③编写代码实现接口。

@Service
public class Helloimple implements IHello {
	@Override
	public String say (String msg ) {
		System.out.println(”你好:”+ msg);
		return msg; 
	}
}	

Dubbo 的@Service注解用于暴露服务,其可配置的属性如下:

version
指定该服务的版本。

group
服务所属分组,当一个接口有多种实现时,可以用 group 区分。

cache
该服务的缓存策略。

1)lru基于“最近最少使用”原则删除多余缓存,保持最热的数据被缓存。
2)threadlocal 当前线程缓存,比如一个页面渲染,用到很 portal ,每个 portal 要去查用户信息,通过线程缓存,可以减少这种多余访问。

async
基于 NIO 的非阻塞实现井行调用,客户端不需要启动多线程即可完成并行调用多个远程服务的功能,相对多线程开销较小。

delay
延迟暴露服务,如果你的服务需要 warmup 时间,比如初始化缓存、等待相关资源就位等,可以使用delay 进行延迟暴露。为-1时,则表示延迟到 Spring 初始化完成后,再暴露服务(基于 SpringContextRefreshedEvent 事件触发暴露)。

timeout
调用服务时的超时时间,单位为秒。

mock
设为 true,表示使用缺省 Mock 类名,即接口名+ Mock 后缀,服务接口调用 Mock 实现类,该Mock类必须有一个无参构造函数,与 Local 的区别在于,Local 总是被执行,而 Mock 只在出现非业务异常(比如超时、网络异常等)时执行;Local 在远程调用之前执行, Mock 在远程调用后执行。

retries
远程服务调用重试次数,不包括第一次调用,不需要重试设为0。

token
令牌验证。如果为空,表示不开启;如果为 true,表示随机生成动态令牌;否则使用静态令牌。令牌的作用是防止消费者绕过注册中心直接访问,保证注册中心的授权功能有效,如果使用点对点调用,需关闭令牌功能。

dynamic
服务是否动态注册,如果设为false ,注册后将显示 disable 状态,需人工启用,并且服务提供者停止时,也不会自动取消住册,需人工禁用。

register
该协议的服务是否注册到注册中心。

deprecated
服务是否过时,如果设为true消费方引用时将打印服务过时警告error日志。

accesslog
设为 true,将向 logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件。

executes
在暴露服务中的每个方法服务器端并发执行(或占用线程池中的钱程数)。

actives
在暴露服务中的每个方法客户端并发执行(或占用连接的请求数)。

loadbalance
负载均衡策略,可选值为random,roundrobin,leastactive, 分别表示随机、轮循、最少活跃调用。此参数均为小写。

connections
限制客户端服务使用连接数(如果是长连接,比如Dubbo协议,connections 表示该服务对每个提供者建立的长连接数)。

protocol
该服务所使用的协议,不同服务在性能上适用不同协议进行传输 比如大数据用短连接协议,小数据大并发用长连接协议,默认为 Dubbo。
• Dubb 协议,采用单一长连接和 NIO 异步通信,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
• Hsessian 协议,传人传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。
• RMI协议,采用 ]DK 标准的 java. rmi实现,常规远程服务方法调用,与原生 RMI 服务互操作。
• HTTP 协议,可用浏览器查看,通过表单或 URL 传人参数。
• WebService协议, SOAP 文本序列化,多用于系统集成,跨语言调用。
• Thrif 协议 ,对thrift ( Facebook的RPC 框架 )的原生协议的扩展。

④在 appaction.properties 文件中配置 Dubbo。

spring.dubbo.application.name=provider
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.port=-1
spring.dubbo.scan=org.book

spring.dubbo.application.name
当前应用名称,用于注册中心计算应用间依赖关系

spring .dubbo .application. version
当前应用的版本。

spring.dubbo application.logge
击输出方式,可选:slf4j 、jcl 、log4j、 jdk。

spring.dubbo.registry.address
服务所使用的注册中心,A://B:C ,其中A为注册中心类型, B为注册中心所在 ip 地址, C为注册中心的端口号,配置集群时候以逗号分隔,例如 A://Bl:C1,A://B2:C2。
Zookeeper 注册中心:使用 zookeeper 作为注册中心。
Multicast 注册中心:以广播的方式在地址段 224.0.0.0 - 239.255.255.255 现服务的注册与发现,适合小规模应用或开发阶段使用.
Redis 注册中心:使用 redis 作为注册中心,通过心跳的方式检测脏数据,服务器时间必须相同,并且对服务器有一定压力。
Smple 注册中心:注册中心本身就是一个普通的 Dubbo 服务,可以减少第 方依赖,使整体通信方式一致。

spring.dubbo. registry.use name
登录注册中心用户名,如果注册中心不需要验证可不填。

spring.dubbo. registry.password
登录注册中心密码,如果注册中心不需要验证可不填。

spring.dubbo.registry.timeout
注册中心请求超时时间(毫秒)。

spring.dubbo.registry.register
是否向注册中心注册服务,如果设为 false ,将只订阅,不注册。

spring.dubbo.registry.subscribe
是否向注册中心订阅服务,如果设为 fa!吨将只注册,不订阅。

spring.dubbo.registry.transporter
网络传输方式,可选mina、netty。

spring.dubbo.protocol.name
服务所使用的协议名称。

spring.dubbo.protocol.port
服务提供方所暴露的端口号,多个服务提供方不可重复。
Dubbo 协议缺省端口 20880, RMI协议缺省端口为 1099, HTTP和Hessian协议缺省端口为 80。如果配置为-1 或者没有配置,则会分配一个没有被占用的端口。

spring.dubbo.scan
扫描服务所在包路径。

sp ing.dubbo.protocol.threadpool
线程池类型,可选: fixed、cached。

spring.dubbo.protocol.threads
服务线程池大小(固定大小)。

spring.dubbo.protocol.iothreads
IO 线程油大小 (固定大小)。

spring.dubbo.protocol.accepts
服务提供方最大可接受连接数。

spring.dubbo.protocol.payload
请求及响应数据包大小限制,单位为字节,默认为 8838860B ( 8MB)。

spring.dubbo otocol.serialization
协议序列化方式,当协议支持多种序列化方式时使用,比如 Dubbo Hessian2、Java 原生,以及HTTP 协议的 JSON 等。

消费方
①新建 Spring Boot 应用。
Maven参数

groupid:org.book.rpc.dubbo
artifactId:dubbo-client
version:0.0.1-SNAPSHOT
packaging:jar

②在 pom.xml 文件中添加 Dubbo与接口工程的依赖

<dependency>
	<groupid>io.dubbo.springboot</groupid>
	<artifactid>spring-boot-starter-dubbo</artifactid>
	<version>1.0.0</version>
</dependency>
<dependency>
	<groupid>org.book.rpc.dubbo</groupid>
	<artifactid>dubbo-api</artifactid>
	<version>0.0.1-SNAPSHOT</version>
</dependency> 

③编写远程调用 Dubbo 服务.

@Component
public class InvokeService {
	@Reference
	public IHello hello; 
}

Dubbo 的@ Reference 注解可以用于生成远程服务代理,其可配置的属性如下。
version
服务版本,与服务提供者的版本一致。

group
服务分组 当一个接口有多个实现时,可以用分组区分,必须和服务提供方。

timeout
服务方法调用超时时间(毫秒)。

retries
远程服务调用重试次数,不包括第一次调用,不需要重试请设为0。

connections
设置提供者的最大连接数。

loadbalance
负载均衡策略 可选值为 random、roundrobin,、leastactive ,表示:随机、轮循、最少活跃调用。此参数均为小写。

async
是否异步执行 不可靠异步 只是忽略返回值 不阻塞执行线程。

check
启动时检查提供者是否存在 true报错 false 忽略。

init
是否等到有服务注入或引用该实例时再初始化。

protocol
只调用指定协议的服务提供方,其他协议忽略。

cache
以调用参数为key ,缓存返回结果,可选:lru、threadlocal、jcache 等。

④在 appaction.properties文件中配置Dubbo。

spring.dubbo.application.name=consumer
spring.dubbo.registry address=zookeeper //127.0 0. 1:2181
spring.dubbo.scan=org.book

与服务提供方的配置一致,指定与服务提供方一致的注册中心地址,并提供不同的 application.name 便可完成调用端的配置。

⑤测试调用
Spring Boot 的人口处获得刚编写的用于调用 Dubbo服务的 InvokeService 并依次启动 Zookeeper服务方、消费方工程完成远程调用。

@SpringBootApplication
public class DubboClientApplication {
	public static void main (String[ ] args) {
		ConfigurableApplicationContext run= SpringApplition.run(DubboClientApplication.class,args);
		InvokeService service= run.getBean(InvokeService.class);
		System.out.println("收到返回结果"+ service.hello.say("rpc"));
	}
}

网关
模块之间互相调用时,为了降低由网络波动带来的不确定性因素并提升系统安全性,生产环境中所有模块一般都运行在内网环境中,并单独提供一个工程作为网关服务,开放固定端口代理所有模块提供的服务,并通过拦截器验证所有外部请求以达到权限管理的目的。外部应用有可能是 App 、网站或桌面客户端,为了达到通用性,网关服务一般为Web服务,通过 HTTP 协议提供 RESTful 风格的 API 接口。
①新建 Spring Boot应用。
Maven参数

groupld: org.book.rpc.dubbo
artifactld: dubbo-getway
version: 0.0.1- SNAPSHOT
packaging : jar

②在 pom.xml 文件中添加 Dubbo与接口工程的依赖

<dependency>
	<groupid>io.dubbo.springboot</groupid>
	<artifactld>spring- boot- starter-dubbo</artifactld>
	<version>l.0.0</version>
</dependency>
<dependency>
	<groupld>org.book.rpc.dubbo</groupld>
	<artifactld>dubbo-api</artifactld>
	<version>0.0 .1-SNAPSHOT</version>
</dependency>
<dependency>
	<groupld>org.springframework.boot</groupld>
	<artifactid>spring-boot-starter-web</artifactid>
</dependency>

spring-boot-starter-web
支持Web应用开发,包含Tomcat和Spring-MVC。

③在 appaction.properties 文件中配置。

spring.dubbo.application.name=geteway
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.registry.register=false
spring.dubbo.scan=org.book
server.port=8081

网关服务只负责调用模块的服务,通过 spring.dubbo.registry.register=false 限制只调用服务,并不注册
server.port
网关服务所访问端口号。

④编写用于调用 Dubbo 服务的编写控制器。

@RestController
public class RpcController {

	@Reference
	private IHello hello ;
	
	@RequestMapping(value = "/")
	public String say() {
		return hello.say("rpc"); 
	}
}

使用注解@RestControlle 标识当前类为一个 Servlet ,并通过注解@RequestMapping映射请求,相当于 Servlet在web.xrnl 的配置。

@RestController 继承自@Controller,它将自动把 response 的返回结果进行json序列化,并且可以为请求链接增加 .json、.xml 后缀来指定序列化方式。如果想使用自@Controller 达到返回json 结构的结果,则需要为每个@RequestMapping 增加@ResponseBody 注解。

⑤编写限验证逻辑
Dubbo 所暴露的接口由网关服务转为 HTTP 协议的 API 调用,这些接口通常需要安全检查,所以这里新建 Handlerinterceptor拦截器的实现类用来模拟最简单的权限验证。

public class Requestinterceptor implements Handlerinterceptor{

	@Override
	public void afterCompletion (HttpServletRequest request,HttpServletResponse response,Object obj,Exception exception)throws Exception{
	}
	
	@Override
	public void postHandle (HttpServletRequest request,HttpServletResponse response,Object obj,ModelAndView modelAndView)throws Exception{
	}
	
	@Override
	public boolean preHandle (HttpServletRequest request,HttpServletResponse response,Object obj)throws Exception{
		String token = request.getParameter("token");
		if(token!=null&&token.equel("1")){
			return true;
		}
		response.getWriter("token error");
		return false;
	}
}

实现 HandlerInterceptor接口后,Spring 提供了3个方法用于在不同阶段满足过滤的需求。

afterCompletion()
当前对应的 Interceptor 的preHandle 方法的返回值为 true 时执行,主要用于资源清理工作。

postHandle()
当前请求进行处理之后执行,主要用于日志记录、权限检查、性能监控、通用行为等。

preHandle()
在请求处理之前执行,主要用于权限验证、参数过滤等。

Spring 允许多个拦截器同时存在,通过拦截器链管理。
返回值为 true 时执行下一个拦截器,直到所有拦截器执行完 ,再运行被拦截的 Controller。
返回值为 false 时不再执行后续的拦截器链及被拦截的 Controller。

⑥配置拦截器。

@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {
	@Override
	public void addinterceptors(InterceptorRegistry registry){
		registry.addinterceptor(new Requestinterceptor()).addPathPatterns ("/**");
		super.addinterceptors(registry); 
	}
}

WebMvcConfigurerAdapter 用于进行WebMVC 环境中的相关配置,通过对 addinterceptors()方法重写可使之前编写好的拦截器生效 。@Configuration 注解则用于标识当前为一个配置类 ,在Spring Boot 启动时会被加载。
使用 addPathPatterns 方法设置拦截规则 excludePathPatterns 方出则可以设置排除的拦截规则。
此处设置的 addPathPatterns("/**")表示拦截所有请求,如果只拦截 account 目录下的请求,则写为/account/**

⑦测试调用。
依次启动 Zookeeper、服务提供方、网关应用。
访问 http://localhost:8081:由于缺少 token 参数,拦截器生效,请求被拦截则直接返回token error 信息。
访问 http://localhost:8081?token=1: 调用服务并返回结果。

监控中心
Dubbo 官方提供了 dubbo-admin 子项目,主要用于路由规则、动态自己置、服务降级、访问控制、权重调整、负载均衡等管理。

①从官网下载 Dubbo源码。

git clone https://github.com/alibaba/dubbo.git 

②编译 Dubbo
Dubbo 也是基于 maven 构建,所以这里需要先在开发环境中安装 Maven。maven安装很简单,不在叙述。

③配置及启动监控中心。
当项目编译成功后,进入 dubbo-admin 子项目target 目录,将编译好的dubbo-admin-2.5.5-SNAPSHOT.war解压后移入Tomcat/webapps/ROOT目录,并修改 dubbo-admin 的WEB-INF目录下 dubbo .propeties 文件来进行配置。

dubbo.registry.address=zookeeper://127.0.0.1:2181 #注册中心地址
dubbo.admin.root.password=root #root管理员的登陆密码
dubbo.admin.guest.password=guest #游客登陆密码

依次启动 Zoopkeeper、Tomcat便可在浏览器中访问监控界面。

服务管理
启动服务提供方或服务消费方项目,便可在服务治理目录下的提供者与消费者页面中查看对应的项。

服务:
服务提供方中所暴露的具体服务,与注解@Service 相关。

应用
服务提供方或消费方的名称,由appaction.properties 配置文件中的 spring.dubbo.application.name 参数设置。

负载均衡
当并发请求与计算的需求越来越大,一台机器难以处理时,将提供该服务的应用部署在多个机器上,共同向注册中心提交服务,用户发起请求调用服务时,则从注册中心根据负载策略找服务提供方,最终完成此次调用。

为了适应不同的场景,Dubbo 提供了4种负载均衡策略,并可以通过实现com.alibaba.dubbo.rpc.cluster.LoadBalance 接口扩展自定义策略。

配置策略时可以在服务提供方(@ Service 注解)与消费方(@Reference 注解)修改 LoadBalance参数,也可以在 dubbo-admin 中使用图形化界面完成配置。当同时配置了不同的策略时,dubbo-admin优先级大于@Reference ,最后为自@Service。

dubbo-admin 配置负载均衡位于服务治理目录下的负载均衡页面。新增配置并提供服务名称、方法名称、负载策略,保存后便可完成配置。

Random LoadBalance:
随机,按权重设置随机服率,默认策略。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
启动服务提供方项目后,在 dubbo-admi 的服务治理目录下的提供者页面中,使用倍权与半权功能调节权重值。
例如将同一服务部署两次,会得到两个服务提供者,分别设置权重值为100、200 ,假设当前有 3000 个并发请求,权重值为100服务将接受 1000 个请求,而权重值为 200 的则接受 2000 个请求。

RoundRobin LoadBalance:
轮循,按公约后的权重设置轮循比率。
存在慢的提供者累积请求的问题,比如:第二台机嚣很慢,但没崩溃。当请求调到第二台时就卡在那里,久而久之,所有请求都卡在第二台机器上。

LeastActive LoadBalance:
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

ConsistentHash LoadBalance
一致性 Hash ,相同参数的请求总是发给同一提供者。
当某一台提供者崩横时,原本发往该提供者的请求,基于虚拟节点被平摊给其他提供者,不会引起剧烈变动。

服务降级
分布式环境下服务之间存在一定依赖关系,当整个依赖链中的某服务崩渣或网络不通时,远程服务无法调用成功井抛出RpcException异常,为了避免由一个服务崩横而引起的连锁反应以及保持主业务的正常运行,可以对服务进行降级处理,在调用失败后返回默认数据。
在有部分服务崩溃时访问网站,页面中由崩溃的服务提供的数据为空会比整个网站无法打开要好得多。

Dubbo 通过 mock 实现服务降级,并提供了两种配置方式。

1.简单降级:
设置服务消费方@Reference注解的mock参数为return null ,表示当远程调用失败时直接返回null,或返回其他默认值(return something)。

@Reference(mock = "return null")
private IHello hello ; 

2.复杂降级
mock 可以指定一个具体的类,当调用失败时执行,以满足复杂的业务逻辑。 mock 需要实现服务接口,类名规范为:接口名+Mock。
①在接口工程中创建 mock类。

public class IHelloMock implements IHello {
	public String say (String msg) {
		return "降级数据";
	}
}

②在服务提供方,配置注解@ Service 指定 mock 类所在位置。

@Service(mock = "org.book.service.IHelloMock")
public class Helloimple implements IHello {
	@Override
	public String say(String msg){
		try {
			//模拟请求超时
			Thread.sleep(10*1000) ;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return msg ;
	}
}

③在服务调用方,配置注解@Reference 设置 mock为 true 开启降级。

@Reference(mock = "true" )
private IHello hello ;

集群容错
为了提高系统可用性,将服务提供方部署成多个组成服务集群,在消费方调用服务失败或超时,Dubbo可以配置多种策略重新调用集群中的其他服务提供方。

在提供方的@ Service 和消费方的@Reference 注解中配置 cluster 参数,或者用 application.properties 中的 spring.dubbo.service.cluster 参数来指定容错策略。

Failover Cluste
失败自动切换,当出现失败时,重试其他服务器。(默认)
通常用于读操作,但重试会带来更长延迟。
可以通过在服务提供方的@ Service 或消费方的@Reference 注解中设置 retries 参数来指定重试次数(不含第一次)。

Failfast Cluster
快速失败,只发起一次调用,失败立即报错。
通常用于非幕等性的写操作,比如新增记录。

Failsafe Cluster
失败安全,出现异常时,直接忽略。
通常用于写人审计日志等操作。

Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。
通常用于消息通知操作。

Forking Cluster
并行调用多个服务器,只要一个成功即返回。
通常用于实时性要求较高的读操作,但需要展费更多服务资源。

Broadcast Cluster
广播调用所有提供者 ,逐个调用,任意一台报错则报错。
通常用于通知所有提供者更新缓存或日志等本地资源信息。

四、Spring Cloud
Spring Cloud 是基于 Spring Boot 一整套实现微服务的框架。它提供了微服务开发所需的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等组件。
Spring Cloud 有众多的子项目,各自之间都有自己的版本号。为了方便统一由 spring-cloud-dependencies 行管理,使用时只需引人具体的依赖而不需要提供版本号。

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupid>org .springframework.cloud</groupid>
			<artifactid>spring-cloud-dependencies</artifactid>
			<version>${spring-cloud.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement> 

dependencyManagement是Maven 用于管理依赖的一种方式,它只申明依赖但并不直接引入。
Spring Boot Spring Cloud 版本依赖关系如下:
Angel 版本对应 Spring Boot 1.2.x
Brixton 版本对应 Spring Boot 1.3.x
Camden 版本对应 Spring Boot 1.4.x
Dalston 版本对应 Spring Boot 1.5.x
后续示例均基于 Dalston.RELEASE 版本进行。

注册中心
与Dubbo 一样, Spring Cloud 支持 Zookeeper 作为注册中心,但官方更推荐 Spring Cloud Netflix的Eureka。
Spring Cloud Netflix是Spring Cloud 的子项目之一,主要内容是对 Netflix 公司一系列开源产品的包装,它为Spring Boot 应用提供了自配置的 Netflix oss 整合,通过一些简单的注解,开发者就可以快速地在应用中配置一些常用模块井构建庞大的分布式系统。它主要提供的模块包括:服务发现( Eureka )、断路器(Hystrix )、智能路由( Zuul )、客户端负载均衡( Ribbon)等。

①新建 Spring Boot 工程,并在创建时勾选 Eureka Server 依赖。
Maven参数:

groupid: org.book.rpc.cloud
artifactid:cloud-eureka
version:0.0.1-SNAPSHOT
packaging:jar

pom依赖:

<dependency>
	<groupid>org.springframework.cloud</groupid>
	<artifactid>spring-cloud-starter-eureka-server</artifactid>
</dependency>

②Spring Boot 人口开启 Eureka 服务。

@SpringBootApplication
@EnableEurekaServer
public class CloudEurekaApplication {
	public static void main(String[] args) {
		SpringApplication.run(CloudEurekaApplication.class, args); 
	}
}

@EnableEurekaServer
Spring Boot 封装了 Eureka ,通过该注解将本应用变为 Eureka 服务器。

③在 application.properties 配置 Eureka。

server.port=8082
eureka.instance.prefer-ip-address=true
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://localhost:${server.port}/eureka/

server.port
该服务访问端口。

eureka.instance.hostname
使用主机名广播服务。

eureka.instance.pefer-ip-address
使用 ip 地址 播服务。

eureka.client.egister-with-eureka
是否注册到 eureka 服务器。由于应用本身就是注册中心,所以设置为false。

eureka.client.fetch-registry
eureka 服务器检索服务,由于本应用的职责就是维护服务实例,所以设置为false。

eureka.client.service-url
用于服务注册和服务检索的地址 其中 service -url 后面需要的是 Map<String ,String>类型参数,所以 defaultZone 可以自己定义。
KaTeX parse error: Expected '}', got 'EOF' at end of input: …ord@localhost :{server.port} /eureka /为注册与获取服务增加 HTTP 基础身份验证。

eureka.server.enable-self-preservation
是否关闭 ureka 自我保护模式,当网络产生技动无法请求成功但服务提供方并未崩溃时,自我保护模式并不会删除已在 Eureka 注册表中注册的服务,在对应用频繁的开发环境中建议关闭,生产环境中开启。
eureka.server.eviction-interval-time-in-ms
服务清理间隔(单位:毫秒,默认 60*1000)。

eureka.instance.lease-renewal-interval-in-seconds
设置服务租约时间(单位秒,默认 30 开发环境中可以降低此参数以加快服务注册过程,但产环境中建议保持默认值。

注册服务
Spring Cloud 基于 HTTP 协议的 RESTful创风格的 API进行服务之间的通信,在注册服务时会明显地发现与编写 Spring Controller 没有太大区别。

①新建 Spring Boot 工程,并在创建时勾选 Eureka Discovery 依赖。
Maven

groupid:org.book.rpc.cloud
artifactld:cloud-service
version:0.0.1-SNAPSHOT
packaging:jar

pom

<dependency>
	<groupld>org.springframework.cloud</groupld>
	<artifactid>spring-cloud-starter-eureka</artifactid>
</dependency> 

②在 Spring Boot 人口开启服务发现与注册支持。

@EnableDiscoveryClient
@SpringBootApplication
public class CloudServiceApplication {
	public static void main(String[] args) {
		SpringApplication.run(CloudServiceApplication.class, args); 
	}
}

@EnableDiscoveryClient
开启 DiscoveryClient 的实例 Eureka Server 进行交互,负责注册服务、租约续期、检索服务、取消租约等功能。

③在 application.properties 配置 Eureka。

spring.application.name=SERVER-NAME
server.port =${PORT:${SERVER PORT:O}}
eureka.client.service-url.defaultZone=http://localhost:8082/eureka 

spring.application.name
应用名称,在服务调用时将使用此参数做依赖计算。

server.port
应用访问喘口号。KaTeX parse error: Expected '}', got 'EOF' at end of input: {PORT:{SERVER_PORT:0}}表示自动分配一个未使用的端口 ,如果需要直接访问该服务则直接提供一个具体的端口号便可。

eureka.client.service-url
注册中心所在地址,如果 eureka 为集群,则通过逗号分隔配置所有的注册中心地址。

④编写服务。
与服务注册的代码 Spring MVC Controller 并无区别,这样做极大地方便了对原先使用 Spring MVC的项目进行微服务化重构的工作。

@RestController
public class ServerController{
	@RequestMapping(value = "hello")
	public String hello (@RequestParam("param") String param) {
		return "rpc:" + param; 
	}
}

调用服务:
各个微服务模块都是以 HTTP 协议暴露服务的,调用服务时只需使用类似JDK的URLConnection或Spring RestTemplate (HTTP 客户端) 便可,而 Spring Cloud Netflix 提供了 Ribbon与Feign 工具来简化调用过程,并且支持客户端负载均衡、熔断等功能。

①新建 Spring Boot 工程,井在创建时勾选 Eureka Discovery依赖。
Maven:

groupid:org.book.rpc.cloud
artifactid:cloud-client
version:0.0.1-SNAPSHOT
packaging:jar

Spring Cloud 应用都需要引人 EurekaDiscovery 来接入到 Eureka 运行环境中,所以需要在 Spring Boot 人口处通过@EnableDiscoveryClient 注解添加发现服务能力,并且在 application.properties 中配置 Eureka 地址、应用名称、访问端口等基本信息。

Ribbon
Ribbon 是一个基于 HTTP和TCP 客户端的负载均衡器,通过客户端中配置的 ribbonServerList 服务端列表去轮询访问以达到均衡负载的作用。

Ribbon 核心组件
Rule-从服务列表中如何获取一个有效服务。
Ping - 后台运行线程用来判断服务是否可用。
ServerList-服务列表。

②在 pom.xml 文件中引人 ribbon 依赖

<dependency>
	<groupid>org.springframework.cloud</groupid>
	<artifactid>spring-cloud-starter-ribbon</artifactid>
</dependency>

③在 Spring Boot 人口处注人 RestTemplate 实例。

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
	return new RestTemplate(); 
}

RestTemplate
通过 Spring 自带的 Rest 客户端,可以方便地发起 HTTP 请求并且将结果序列化。
@LoadBalanced
该注解将开启 Ribbon 负载均衡模式 开启后 Ribbon 拦截 RestTemplate 发起的请求,井实现负载均衡。

④调用服务。

@Autowired
private RestTemplate restTemplate;
public String say() {
	return restTemplate.getForObect("http://SERVER/hello?param=cloud",String.class);
}

http://SERVER/hello?param=cloud 是服务具体所在地址及传递的参数 ,与URL不同的是原本主机名+端口的地址变为服务名称SERVER ,由此可以推断出 Ribbon 户端根据服务名称从Eureka 注册中心寻找具体服务地址。在有多个服务提供者时由 Eureka 注册中心的服务列表与 Ribbon配合完成负载均衡。

⑤在 application.properties 文件中配置 Ribbon。
当请求失败时 ,如下配置可以让 Ribbon 重试链接及更换其他服务提供方。

spring.cloud.loadbalancer.retry.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutinMilliseconds=lOOOO
ribbon.ConnectTimeout=250
ribbon.ReadTimeout=lOOO
ribbon.OkToRetryOnAllOperations=true
ribbon.MaxAutoRetriesNextServer=2
ribbon.MaxAutoRetries=1 

spring.cloud.loadbalancer.retry.enabled
是否开启重试机制,默认为关闭。

hystrix.command.default.execution.isolation.thread.timeoutlnMilliseconds
断路器的超时时间,需要大于 ribbon 的超时时间, 则不会触发重试。

ribbon.ConnectTimeout
请求连接的超时时间。

ribbon.ReadTimeout
请求处理的超时时间。

ribbon.OkToRetryOnAllOperations
对所有操作请求都进行重试。

ribbon.MaxAutoRetriesNextServer
重试负载均衡其他实例的最大重试次数,不包括首次调用。

ribbon.MaxAutoRetries
同一个服务提供方最大重试次数 不包括首次调用。

以ribbon 开头的配置项是针对所有服务的调用设置,如果需指定某一具体服务,只需在前面增加具体的应用名称SERVER.ribbon.ConnectTimeout=250。

⑥配置 Ribbon 负载均衡策略。

@Configuration
public class RibbonConfiguration {
	@Bean
	public IRule ribbonRule() {
		return new BestAvailableRule(); 
	}
}

Ribbon提供多种负载策略,由 IRule 进行管理,通过继承 ClientConfigEnabledRoundRobinRule 可自定义负载策略。

BestAvailableRule
最大可用策略,即先过滤出故障服务器 然后选搏一个当前并发请求数最小的。

AvailabilityFilteringRule
可用过滤策略 先过指出故障或并发请求大于阔值 一部分服务实例 然后再以线性轮询的方式从过滤后的实例清单中选出。

WeightedResponseTimeRule
带刷版的轮询策略 对各个服务器 应时间 时放日军然后再采用轮询的方式来获取相应的服务器。

RetryRule
在选定的负载均衡策略机上重试机制。

RoundRobinRule
以轮询的方式依次将请求调度不同的服务器(默认策略)。

RandomRule
随机选择个服务提供方。

ZoneAvoidanceRule
区域感知轮询负载均衡。

使用@RibbonClients 注解对所有服务的负载策略配置生效。

@EnableDiscoveryClient
@RibbonClients(defaultConfiguration = RibbonConfiguration.class)
@SpringBootApplication
public class CloudClientApplication {
	public static void main(String[] args) {
		SpringApplication run(CloudClientApplication.class,args); 
	}
]

defaultConfiguration 为负载策略配置文件。

如果希望针对某一具体服务配置负载策略 可以使用@RibbonClients 注解单独配置。

@Configuration
@RibbonClient(name = "SERVER", configuration = RibbonConfiguration.class)
public class TestConfiguration {
}

name为服务名称,configuration 为负载策略配置文件。

Feign
Feign 是一个声明式的 Web 服务客户端,通过简单的注解便可像调用本地方法一样调用远程服务。Spring Cloud Feign 添加了 Spring MVC 注解支持 ,并整合了 Ribbon和Eureka 来为 Feign 提供负载均衡功能。

②在 pom.xml 文件中引人 Fegin 依赖。

<groupid>org.springframework.cloud</groupid>
	<artifactid>spring-cloud-starter-feign</artifactid>
</dependency> 

③在 Spring Boot 人口处开启 Fegin 支持。

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class CloudClientApplication {
	public static void main(String [] args) {
		SpringApplication.run(CloudClientApplication.class, args); 
	}
}

@EnableFeignClients。
将自动扫描所有@FeignClient 注解。

④编写调用接口。
通过接口告知 Fegin 调用信息,定义的方法( hello ())则是来自于服务提供方暴露的具体服务方法( RestController)。

@FeignClient(name = "SERVER")
public interface ServerClient{
	@RequestMapping(value = "hello")
	public String hello(@RequestParam ("param") String param); 
}

name
服务提供方的应用名称。

url
手动指定调用地址。

decode404
是否开启 decoder 解码,当请求发生 404 误会调用decoder进行解码;否则抛出 FeignException。

configuration
指定配置类,用于自定义 Encoder、Decoder、LogLevel、Contract。

path
定义当前 fegin调用时的统一前缀。

fallback
指定容错处理类 周用发生错误时会调用该指定的类。

fallbackFactory
指定容错处理的工厂类 用于减少重复的容错处理类编写。

⑤在 application.properties 中配置 Fegin。

feign.compression.request.enabled=true
feign.compression.response.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048

feign.compression.request.enabled
开启请求压缩。

feign.compression.response.enabled
开启返回值压缩。

feign.compression.request.mime-types
设置压缩类型。

feign.compression.request.min-request-size
设置压缩最小闻值。

⑥调用服务。

@Autowired
private ServerClient serverClient;
public String say() {
	return serverClient.hello("cloud"); 
}

Spring Cloud 应用启动时,Feign职会扫描标有@FeignClient 注解的接口生成代理,为每个接口方法创建一个 RequestTemplat 对象,并封装发起 http请求时所需的所有信息,最终注册到 Spring 容器中。

Zuul 网关
Spring Cloud 提供了 Zuul 作为服务网关 Dubbo 务网关不同的是, Zuul 并不直接调用服务,而是通过动态路由提供代理服务,在具体开发过程中也更为简单方便。

①新建 Spring Boot 工程,并在创建时勾选 Eureka Discovery 依赖。
Maven参数

groupid:org.book.rpc.cloud
artifactid:cloud-getway
version:0.0.1-SNAPSHOT
packaging:jar 

②在 pom.xml文件中引人 Zuul 依赖。

<dependency>
	<groupid>org.springframework.cloud</groupid>
	<artifactid>spring-cloud-starter-zuul</artifactid>
</dependency> 

③在 Spring Boot 人口处开启 Zuul 支持。

@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class CloudGatewayApplication{
	public static void main(String[] args){
		SpringApplication.run(CloudGatewayApplication.class,args);
	}
}

EnableZuulProxy
设置一个Zuul 的服务端点,并开启反向代理过滤器,以达到将请求转发到后端的服务提供方的目的。

④在 application.properties 配置 Zuul。

spring.application.name=geteway
server.port=8083
eureka.client.service-url.defaultZone=http://localhost:8082/eureka
zuul.routes.SERVER.path=/server/**
zuul.routes.SERVER.service-id=SERVER 

zuul. routes.*.path
拦截请求的路径,其中星号( SERVER )为自定义的分组标记,用于路由配置。

zuul.routes.*.service-id
根据分组标记( SERVER )将拦截到的请求转发到某服务提供方的名称。

zuul.routes.*.url
根据分组标记( SERVER )将拦截到的请求转发到一个具体的 URL 地址。

⑤过滤器权限验证。
通过继承 ZuulFilter 类实现过滤功能,与 Spring MVC的 HandlerInterceptor 类似。

public class RequestFilter extends ZuulFilter{

	@Override
	public boolean shouldFilter(){
		return true;
	}
	
	@Override
	public Object run(){
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		String token= request.getParameter("token");
		if (token== null ||!token.equals("1")){
			ctx.setResponseBody("token error") ;
			ctx.setSendZuulResponse(false);
		}
		return null;
	}
	
	@Override
	public String filterType(){
		return "pre";
	}
	
	@Override
	public int filterOrder(){
		return 0 ; 
	}
}

shouldFilter()
返回 Boolean 值,标识该过滤器是否开启。

filterType()
返回 个字符串,标识该过滤器在何时调用。
pre:在请求被路由之前调用。
routing:在路由请求时候被调用。
error: 处理请求时发生错误时被调用。
post:在 routing error 过滤器之后被调用。

filterOrder()
返回 个山,标识该过滤器在过滤器链中执行的顺序。

run()
过滤器的具体逻辑。

ctx.setResponseBody(“token error”); 设置请求返回值。

ctx.setSendZuulResponse(false)设置不对该请求进行路由操作。

当过滤器配置完成后,便可以在程序人口处注人该过滤器使他生效。

@Bean
public RequestFilter logFilter(){
	return new RequestFilter(); 
}

Hystrix 断路器:
当远程请求失败时, Dubbo 通过 mock 实现服务降级与容错,而 Spring Cloud 则提供 Hystrix 达到同样的目的,与之不同的是 Hystrix 是以框架级别角度解决该问题,而 mock 则是以功能角度出发。
Hystrix 通过线程池来隔离资源,在使用时会根据调用的远程服务划分出多个线程池,例如调用产品服务的 Command 放人A 线程池,调用账户服务的 Command 放人 B程池,当调用服务的代码存在bug,或者由于其他原因导致自己所在线程池被耗尽时,不会对系统的其他服务造成影响。
Spring Cloud 提供的 Fegin Ribbon 都非常好地支持了 Hystrix ,只需简单的配置便可完成。

Ribbon:
①在 pom.xrnl 中引人 hystrix 依赖。

<dependency>
	<groupid>org.springframework.cloud</groupid
	<artifactid>spring-cloud-starter-hystrix</artifactid>
</dependency>

②在 Spring Boot 人口处开启 hystrix 支持。

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class CloudClientApplication {
	@Bean
	@LoadBalanced
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}
	public static void main(String[] args) {
		SpringApplication.run(CloudClientApplication.class, args); 
	}
}

@EnableCircuitBreake
开启熔断器。

③调用服务
Ribbon调用服务发生错误时,熔断机制生效,将调用由注解@HystrixCommand的fallbackMethod参数指定的方法,而不抛出服务异常,使整个系统保持正常运行。

@HystrixCommand(fallbackMethod ="fallback")
public String say() {
	return restTemplate.getForObject ("http://SERVER/hello?param=cloud", String.class);
}
public String fallback() {
	return "容错数据";
}

fallbackMethod
指定一个处理回退逻辑的方法,回退方法应与需要熔断功能的方法具有相同返回值,并且要在同一个类中。

commandKey
该熔断器的名称,默认为 default。

defaultFallback
与fallbackMethod参数功能一致。

groupKey
服务所属分组。

ignoreExceptions
调用时发生异常,则触发熔断机制,此参数可设置排除的异常。

threadPoolKey
为该熔断器分配一个自定义名称 配置资源隔离策略时使用。

threadPoolPoolperties
配置该熔断器的钱程池参数。接受多个@ HystrixProperty 参数以 kv 形式配置。
示例:threadPoolProperties = {@HystrixProperty(name =”coreSize”, value ="30")}
coreSize:核心线程地大小和线程地最大值。
maxQueueSize:线程池队列最大值。
keepAliveTimeMinutes:线程池中空闲线程生存时间。
queueSizeRejectionThreshold:限定当前队列大小。

④在application.properties 配置熔断器。

spring.application.name=CLIENT
server.port=8889
eureka.client.service-url.defaultZone=http://localhost:8082/eureka
hystrix.command.default.execution.isolation.strategy=THREAD
hystrix.command.default.execution.isolation.thread.timeoutinMilliseconds=1OOO
hystrix.command.default.execution.timeout.enabled=true
hystrix.command.default.execution.isolation.thread.interruptOnTimeout=true
hystrix.command.default.fallback.enabled=true
hystr x.command.default.circuitBreaker.sleepWindowinMilliseconds=5OOO
hystrix command.default circuitBreaker errorThresholdPercentage=5O
hystrix.command.default.circuitBreaker forceOpen=false
hystrix.command.default.circuitBreaker.forceClosed=false
hystrix.threadpool.default.coreSize=1O 

hystrix.command.*.execution.isolation.strategy
设置熔断器的资源隔离策略。

THREAD :并发请求受线程池中的钱程数量的限制(默认及推荐项)。
SEMAPHORE :并发请求受到信号量计数的限制。
参数中 command 后的 default 为注解中@ HystrixCommand 的commandKey 数设置的值,默认为default。

hystrix.command.*.execution isolation.thread.timeoutlnMilliseconds
超时时间。

hystrix.command.execution.timeout.enabled
是否开启超时。

hystrix.command.execution.isolation.thread.interruptOnTimeout
是否打开超时线程中断。

hystrix.command.*.fallback enabled
设置 fallback 是否可用。

hystrix. command.*.ci cuitBreake .sleepWindowlnMilliseconds
触发熔断的时间闻隔。

hystrix.command.*.circuitBreaker.errorThresholdPercentage
错误比率阀值,当错误超过或等于该值时 后续的请求将直接调用 fallback。

hystrix.command.*.circuitBreake.forceOpen
强制打开熔断器,打开后将强制执行 fallback。

hystrix.command.*. circuitBreake.forceClosed
强制 闭熔断器。

hystrix. threadpool.*.coreSize
核心线程池大小和线程池最大值。
与@HystrixCommand 注解中的 threadPoolProperties 参数一致。

Fegin:
Fegin中已经集成了 Ribbon与Hystrix 依赖 Dalston 版本中默认并未开启,只需简单配置便可实现熔断功能。

①编写回调类。
Fegin通过接口确定调用信息,回调类只需实现接口便可与 Dubbo的mock类似,但不限制回调类的名称。

@Component
public class ServerClientFallback implements ServerClient{
	Override
	public String hello(String param){
		return "容错数据";
	}

另外还可以通过实现 FallbackFactory 接口create方法中返回服务接口的实例以实现回调。

@Component
public class DefaultFallback implements FallbackFactory<Object>{
	@Override
	public ServerClient create(Throwable cause){
		return new ServerClie(){
		@Override
		public String hello(String param) {
			return "容错数据";
		}
	}
}

②配置回调类。

@FeignClient(name="SERVER",fallback=ServerClientFallback.class,fallbackFactory=DefaultFallback.class)
public interface ServerClient{
	@RequestMapping(value = ” hello”)
	public String hello(@RequestParam ("param")String param) ;
}

fallback
指定具体的回调类,即当前接口的实现类。

fallbackFactory
指定回调工厂的实现类,即实现 FallbackFactory 接口的类。

③在application.properties 中开启熔断器。

feign.hystrix.enabled=true 

服务监控
将一个应用部署多次,以满足服务高可用需求,而监控每个应用的运行状态则是必不可少的事,因此Spring Cloud 已经对每个应用的运行状态做了统计,并提供了简单的图形化界面管理工具。
同时活跃的 Spring 社区为 Spring Cloud 提供了 Spring-Cloud-Admin 集成管理工具,低侵人的方式只需简单配置便可完成对分布式环境中各应用的监控。

主要功能如下:
显示应用信息
显示在线状态
日志级别管理
JMX beans 管理
会话和线程管理
应用请求眼踪
应用运行参数信息
显示熔断器信息

spring cloud admin 可以通过 eureka 注册中心中的数据或专门提供的客户端获取应用信息。在Spring Cloud 环境下eureka 是最优选搏,而客户端方式则常用于 Spring Boot 应用中。

①新建 Spring Boot 工程,并在创建时勾选 Eureka Discovery 依赖。
Maven

groupid:org.book.rpc.cloud
artifactid:cloud-admin
version:0.0.1-SNAPSHOT
packaging:jar 

②在 pom.xrnl 文件中引人 admin 依赖。

<dependency>
	<groupid>de.codecentric</groupid>
	<artifactid>spring-boot-admin-server</artifactid>
	<version>1.5.3</ve rsion>
</dependency>
<dependency>
	<groupid>de.codecentric</groupid>
	<artifactid>spring-boot-admin-server-ui</artifactid>
	<version>1.5.3</version>
</dependency> 

③在 Spring Boot 人口处开启 admi 支持。

@SpringBootApplication
@EnableAdminServer
@EnableDiscoveryClient
public class CloudAdminApplication{
	public static void main(String[] args) {
		SpringApplication.run(CloudAdminApplication.class,args); 
	}
}

@EnableAdminServer
标识当前应用是 Spring Cloud 监控应用。

⑤配置客户端。
监控应用中的数据来自于 urek 注册中心,所以要对所有 eureka 应用(在 Spring Boot 人口处添加@EnableDiscoveryClient 注解的应用)进行相应的配置。
在各微服务应用的 pom.xml 文件中设置暴露应用基本信息。

<build>
	<plugins>
		<plugin>
		<groupid>org.springframework.boot</groupid>
		<artifactid>spring-boot-maven-plugin</artifactid>
		<executions>
			<execution>
				<goals>
					<goal>build-info</goal>
				</goals>
			</execution>
		</executions>
		</plugin>
	</plugins>
</build> 

⑥测试。
依次启动注册中心、cloud-service、cloud-client、cloud-admin 后,用浏览器访问 http://localhost:8899 便可看见 Spring Cloud Admin 的管理界面。
虽然 admin 从注册中心的列表中获取巳注册应用,但目前仅展示了应用的基础信息,需要继续对url中的各个应用进行配置以获取应用的运行时及熔断器数据。

应用监控
①在各微服务模块中的 pom.xml 文件中添加监控依赖。

<dependency>
	<groupid>org.springframework.boot</groupid>
	<artifactid>spring-boot-starter-actuator</artifactid>
</dependency>
<dependency>
	<groupid>org.jolokia</groupid>
	<artifactid>jolokia-core</artifactid>
</dependency>
<dependency>
	<groupid>org.springframework.boot</groupid>
	<artifactid>spring-boot-configuration-processor</artifactid>
</dependency>

应用健康信息:
Actuator Spring Boot 提供的监控应用系统数据和管理生产环境的模块,可以使用 HTTP, JMX,SSH,Telnet 等方式管理和监控应用。
HTTP 为例,可以通过浏览器轻松访问如下信息。
/autoconfig 查看自动自己置的使用情况。
/configprops :查看配置属性,包括默认配置。
/beans : bean 及其关系列表,显示一个应用中所有 Spring Beans 完整。
/dump :打印线程枝。
/env :查看所有环境变量。
/env/{name }:查看具体变量值。
/health :查看应用健康指标。
/info :查看应用信息。
/mappings :查看所有 url 映射,即所有@RequestMapping 路径的列。
/metrics :查看应用基本指标。
/shutdown :关闭应用。
/trace :查看基本追踪信息,默认为最新的 HTTP 请求。

JMX Beans
Jolokia 是一个JMX-HTTP 桥,它提供了一种访问JMX beans 方法。Spring-Cloud-Admin 提供 beans 相关信息。

②在 application.properties 文件中配置权限。

management.security.enabled=false

actuator中暴露了很多应用的敏感信息,所以默认进行了权限限制,通过 security.enabled 将其关闭方便配置。

熔断器监控
Hystrix 记录了触发熔断时的数据,并提供了简单的图形化统计面板, Hystrix 数据来自各个应用,能分别查看,管理起来比较麻烦,为了简化 Spring Cloud 的管理,提供了 Turbine 来聚合所有Hystrix ,同时 Spring Cloud Admin 也很好地支持了 Turbine ,只需简单的配置便可集成。

在这里插入图片描述
1.单应用的熔断数据:
在每一个应用中配置熔断器以获取 hystrix.stream数据。
①在 pom.xml 文件中添加依赖。

<dependency>
	<groupid>org.springframework.cloud</groupid>
	<artifactid>spring-cloud-starter-hystrix</artifactid>
</dependency>
<dependency>
	<groupid>org.springframework.cloud</groupid>
	<artifactid>spring-cloud-starter-hystrix-dashboard</artifactid>
</dependency>

Fegin 中虽然已集成了 Hystrix ,但为了让监控数据生效还需再引用。

spring-cloud-starter-hystrix-dashboard
熔断器监控面依赖。

②在 Spring Boot 人口处开启 Hystrix 面板。

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrix
@EnableHystrixDashboard
public class CloudClientApplication {
	public static void main(String [] args) {
		SpringApplication.run(CluoudClientApplication.class, args);
	}
}

通过@EnableHystrixDashboard 面板的支持,如果只想使用 Spring Cloud Admin的Turbine 展示数据,则可以不用依赖 spring-cloud-starter-hystrix-dashboard。

③测试。
启动应用后便可获取熔断器的实时数据。
hystrix 数据地址 http://localhost:8888/hystrix.stream
hystrix dashboard 地址http://localhost:8888/hystrix

hystrix.stream
熔断器的实时数据,ping 数据为空时,访问一个使用了熔断器的服务便可。

hystrix dashboard
将hystrix.stream 地址提供给它,便可解析成可视化图表 启动应用后便可获得聚合了指定应用hystrix.stream。

2.使用Turbine聚合数据:
Turbine 负责整合所有应用的 hystrix.stream 数据,为了分担压力所以将 Turbine独立成 个新的应用。

①新建 Spring Boot 工程,井在创建时勾选 Eureka Discovery依赖。
Maven参数

groupid:org.book.rpc.cloud
artifact:cloud-turbine
version:0.0.1-SNAPSHOT
packaging:jar 

②在 pom.xml 添加Turbine依赖。

<dependency>
	<groupid>org.springfrarnework.cloud</groupid>
	<artifactid>spring-cloud-starter-turbine</artifactid>
</dependency>
<dependency>
	<groupid>org.springfrarnework.cloud</groupid>
	<artifactid>spring-cloud-netflix-turbine</artifactid>
</dependency> 

③在 Spring Boot 人口处开启Turbine。

@EnableTurbine
@SpringBootApplication
public class CloudTurb neApplication { 
	public static void main(String[J args) {
		SpringApplication.run(CloudTurbineApplication.class, args) ;
	}
}

④在 application.properties 配置 Turbine。

spring.application.name=TURBINE
server.port=8892
eureka.client.service-url.defaultZone=http : //localhost:8082/eureka
management.security.enabled=false
turbine.app-config=CLIENT
turbine.aggregator.clusterConfig=default
turbine.clusterNameExpression=new String (default) 

turbine.app-config
指定要聚合熔断数据的应用名称,多个应用以逗号分隔。

turbine.aggregator.clusterConfig
指定需要聚合的集群名称。

turbine.clusterNameExpression
获取集群名表达式。

⑤测试。
启动应用后便可获得聚合了指定应用的 hystrix.stream。

通过 http://localhost:8892/turbine.stream 地址便可访问所有的应用熔断数据/

ping
data:{”reportingHostsLastlOSeconds”:1,”name”:”meta”,”type”:”meta”,”timestamp”:1503519020000 )

turbine.stream 地址传送给 hystrix dashboard便可以解析多个熔断监控图表。

3.Cloud Admin整合Turbine:
在cloud-admin 应用中继续改造以让它能够解析 Turbine 图表,完成统一监控。
①在 pom.xml 中添加 Turbine 依赖。

<dependency>
	<groupid>de.codecentric</groupid> 
	<artifactid>spring boot-admin-server-ui-turbine</artifactid>
	<version>1.5.3</version>
</dependency>

②在 applicaton.properties 中配置 Turbine。

spring.boot.admin.turbine.clusters=default
spring.boot.admin.turbine.location=TURBINE

spring.boot.admin.turbine.location
turbine应用的名称或地址 它将自动寻找并解析turbine.stream 。

spring.boot.admin.turbine.clusters
聚合的集群名称。

③测试。
启动应用后便可在 cloud-admin 的Turbine 目录看到各个应用的统计图表。

统一管理配置文件
在工作中一般会进行开发环境、测试环境、生产环境的区分 不同的环境由不同的配置文件管理,当拆分的模块数量较多时,无疑众多的配置文件会显得混乱并且不便于管理,为此 Spring Cloud 提供了spring-cloud-config-server 结合 SVN或Git 对这些配置文件进行集中管理。

①新建 Spring Boot 工程,并在创建时勾选 Eureka Discovery 依赖。
Maven参数:

groupid:org.book.rpc.cloud
artifact:cloud-config
version:0.0.1-SNAPSHOT
packaging:jar 

②在 pom.xml 文件中引人 Config 依赖。

<dependency>
	<groupid>org .springframework.cloud</groupid>
	<artifactid>spring-cloud-config-server</artifactid>
</dependency>
<dependency>
	<groupid>org.tmatesoft.svnkit</groupid>
	<artifactid>svnkit</artifactid>
</dependency>

svnkit
SVN 客户端支持,此例使用 SVN 作为配置文件管理工具 如果使用 Git,则不必引人该依赖。

③在 application.properties 配置 Config Server。

spring.application.name=CONFIG
server.port=8894
eureka.client.service-url.defaultZone=http://localhost:8082/eureka
spring.profiles.active=subversion
spring.cloud.config.server.svn.url=https://localhost:443/svn/config
spring.cloud.config.server.svn.username=username
spring.cloud.config.server.svn.password=password 

spring.profiles.active
指定当前配置文件管理工具,如果为 Gi 可不写,则将后续配置中的 server. svn 变为 server。
git 便可完成对 Git 工具的配置

spring.cloud.config.server.svn.url
svn 仓库地址。

spring.cloud.config.server.svn.username
svn 访问用户名。

spring.cloud.config.server.svn.password
svn 访问密码。

④上传配置文件到 SV

//文件名:client-dev.properties
config=hello config

⑤测试。
启动工程后用浏览器访问 http://lcalhost:8894/client/dev/便可获得 client-dev.properties 的配置文件内容。

name:"client ”,
profiles: [
” dev”
],
label:null ,
version:null,
state:null,
propertySources:[{
	name:”https://localhost:443/svn/config/trunk/client-dev.properties”,
	source:{
		config:”hello config” 
	}
}
]
}

不难发现,访问的 url 路径与配置文件名存在一定的映射关系。
配置文件名称格式为{ application}-{profile} .properties 对应 url 如下:

/{application)/{profile}{/{label}}
/{ application)-{profile}.yml
/(label}/{application}-{profile}.yml
I {application}-{profile}.properties
/{label}/{application)-{profile}.properties

其中 label 为分支名称, Git默认 master 而SVN 默认 trunk。

⑥应用端配置。
在各微服务模块的 pom.xml 文件中引人依赖

<dependency>
	<groupid>org.springframework.cloud</groupid>
	<artifactid>spring-cloud-starter-config</artifactid>
</dependency>

src/main/resources 目录中新建 boostrap.properties 并配置 Config Server。

spring.cloud.config.name=client
spring.cloud. config.profile=dev
spring.cloud.config.label=trunk
spring.cloud.config.uri=http://localhost:8894/

spring.cloud.config.name
对应SVN 配置文件名称中{ aplication)部分。

sp ing cloud config.profile
对应SVN 配置文件名称中{ profile }部分。

spring.cloud.config.label
对应的分支

spring.cloud.config.uri
ConfigServer 地址。

直接提供 ConfigServer的访问地址意味着普通的 SringBoot 应用可以使用 Config Server 配置,如果基于eureka 注册中心使用的话,需要配置 eureka.client.service-url.defaultZone参数以提供注册中心的出止与 spring.cloud.config.discovery.service-id 参数提供config server 的应用名称。
基于 Spring Boot Dubbo 应用也可以使用。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值