导图社区 Spring Cloud与微服务架构
超级详细的Spring Cloud与微服务架构思维导图分享!下图对服务链路追踪、配置、路由网关、Hystrix、Fegin等内容进行了梳理与总结。本图帮助你深入理解Spring Cloud与微服务架构!
编辑于2019-04-26 07:23:46深入理解Spring Cloud与微服务架构(第七章Feign起)
第七章 Fegin
7.0 Feign简介
采用声明式 API风格接口 将 java HTTp 客户端绑定到内部 将 JavaHttp客户端调用变的简单
7.1 写一个Feign 客户端
1 引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
因为Fegin 是调用微服务的 所以必须引入springBoot 基础依赖和Eureka 依赖
2 配置 正常的eureka 就可以
3 配置类
import static java.util.concurrent.TimeUnit.SECONDS; @Configuration public class FeignConfig { @Bean public Retryer feignRetryer() { return new Retryer.Default(100,SECONDS.toMillis(1),5); } }
重新fignRrtyer
配置 过期时间等
4 启动类
1@EnableEurekaClient
eureka 注解
2@EnableFeignClients
启动 Feign注解
5 实现类
1 类上注解
@FeignClient(value = "eureka-client",configuration = FeignClientsConfiguration.class )
1 表示其是个Fegin客户端类
2 value
调用Eureka_server注册的服务器名称
3 configuration
Fegin的配置类 可以自己重写覆盖
7.2 FeignClient 详解
1 类上注解
1 @Target(ElementType.TYPE)
表示注解目标是接口上
2 @Retention(RetntionPolict.RUNTIME)
表示在Class字节码之中存在
3 @Doucumented
表示该注解被包含在javadoc中
2 @FeignClient 特色
1 插拔式 RestFul 风格 可以和其他组件一起使用 典型的跟Ribbon 配合使用山实现负载均衡
3 方法
1 value()
获取服务器id
2 name()
获取服务器id
3 URl()
硬编码 直接写入服务器地址
4 decode404()
404被解压
7.3 FeignClient 配置类
重写Bean方法
7.4 重源码的角度讲解 Feign 的工作原理
1 启动程序如有有 @EnableFeignClients 注解
2 就扫描有@FeignClient 的注解 连同 注解类名 和属性配置全部读取
3 注入到IOC 中 通过JDKde的代理 当调用FeignCLient 接口里边的方法时 会被拦截 会根据参数生成 RequsetTemplate 对象
7.5 在Fegin中使用HTTPClient 和OKHttp
不懂
7.6 Feign 是如何实现负载均衡的的
1 FeignRibbonClient Configuration类配置了Client的类型
2 容器注入Client 的实现类 LoadBalancerFeignClient 及负载聚恒客户端
3 LoadBalancerFeginClient 中 execute方法(执行请求的方法)
4 execute()内部的executeWithLoadBalancer()方法(通过网络请求实现负载聚恒)
5 excuteWithLoadBalancer()内部有submit()方法内部有个selectServer()方法
6 selectServer() 是悬在负载均衡的方法
7 工程思想
1 Feign去注册中心获取列表 然后Feign负载均衡选择服务器发送请求
第八章 Hystrix
8.1 什么 Hystrix
1 Hystrix 的一个开源项目有熔断功能 Hystrix 通过服务隔离组织联通故障
8.2 Hystrix 解决了什么问题
1 在高并发情况下 如果单一的请求出现故障会导致服务的请求处于阻塞状态,最终走走啊正珍格格服务的线程消耗殆尽,导致崩溃 Hystrix解决的问题就是出现问题马上返回不会继续占用资源
8.3 Hystrix 的设计原理
1 防止当个服务的故障耗尽服务的servletr容器的线程资源
2 快速失败机制,如果某个服务出现了故障,则调用服务的请求快速失败,而是不是线程等待
3 提供回退方案(fallback),请求发生故障时,提供设定好的回退方案
4 使用熔断机制,防止故障扩散到其他服务
5 提供熔断器的监控监控最贱 Hystrix Dashboard 可以实现监控熔断器的状态
8.4 Hystrix 的工作机制
1 当服务中某个API接口失败次数小于阀值熔断器处于关闭状态,API提供正常服务
2 当API 几口失败的次数大于设定的阀门 Hystrix判定API接口出现了故障,打开熔断器,这时候会进入快速失败逻辑(fallback)不执行业务逻辑 请求线程不会处于阻塞状态
3 一段时间后 处于半打开状态 一般请求正常逻辑 一半请求快速失败逻辑 若执行正常逻辑的害还出现失败 则熔断器继续打开 ,若成功了 则关闭熔断器 这样熔断器就有了自我修复能力
8.5 在 RestTemplate 和Ribbon 上使用熔断器
1 依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
2 启动类添加注解
@EnableHystrix
3 操作
1 在要进行熔断的方法上加入注解
@HystrixCommand(fallbackMethod = "hiError")
1 fallbackMethod 洗衣歌方法名为这个的hiError 会走该方法
2 如果错误就会走该方法进行熔断
8.6 在Fegin上使用熔断器
1 说明
因为Fegin集成了 Hystrix 所以不需要新的依赖 启动类上也不需要有什么变动 只需要配置 开启熔断机制 Fegin类上加上相关的回调地址即可
2 配置
#在fegin 上配置是否石油hystrix(熔断机制) feign: hystrix: enabled: true
3 Fegin上注解
@FeignClient(value = "eureka-client",configuration = FeignClientsConfiguration.class,fallback = HyFeignEurekaClientDemo.class)
说明:
回到是个实现当前注解类的一个实体类
4 实体类
1 实现Fegin注解
2 对应的方法写对应的熔断方法
3 类上开启@Component
5 注意
如果扫描不到这个回调类 就把他放在跟controller 同级
8.7 Hystrix Dashboard 监控熔断器的状态
8.7.0
hystrix Dashboard监控熔断器友好化图形展示界面
8.7.1 在RestTemplate 中使用 Hystrix DashBoard
1 先完整搭建一个Ribbon Hystrix
1
2 引入依赖
<!--监控系统组件 Hystrix DashBoard--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--hystrrix-dashBodrd 熔断监控主要依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency>
3 启动类
@EnableHystrixDashboard
4 使用
http://localhost:8764/hystrix.stream
地址+hystrix.stream 显示所有hystrix数据指标
http://localhost:8764/hystrix
到达 Hystrix DashBoard 主界面
具体怎么使用去官方网站上查看
第一行地址
第二行延期时间
第三行 请求地址 我猜的
8.7.2 在Fegin 钟使用 Hystrix DashBoard
跟在RestTemplate 中使用一模一样
注意
需要引入Hystrix起步依赖,因为虽然Fegin包含了Hystrix但不是起步
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
8.7.3 缺点
因为每一个服务器有一个监控 微服务多了 特别难难以掌控
8.8 使用Turbine 聚合监控
注意:父亲依赖要注意版本
第九章 路由网关 Spring Cloud Zuul
9.1 为什么要用 Zuul
1 zuul ribbon eureka 相结合 可以实现智能路由和负载均衡功能 zuul能够将请求流量按照某种策略分发到集中状态多个实类当中
2 网关将所有的API统一管理聚合 并像外部暴露 这样外界不需要知道内部的复杂性 而已也保护内部敏感信息不对外暴露
3 网关可以做用户身份认证 权限认证 防止非法请求调用API接口 对服务器🙏保护作用
4 网关可以实现监控功能,实时日志输出,对请求进行记录
5 网关zuul 可以实现流量监控 在高流量情况下,对服务进行降级
6 API接口从内部分离出来,方便测试
9.2 zuul的工作原理
1 zuul 是通过 Zuulservlet 来进行控制的 核心是一系列过滤器
1 PRE 过滤器
是请求路由到具体服务器之前执行的 可以进行 安全验证,例如身份认证 参数认证
2 ROUTING 过滤器
由 请求路由到具体实例,在默认情况下使用 HTTP client进行网络请求
3 POST 过滤器
他的请求由路由到微服务后执行,一般情况下,用作手机信息,指标,以及相应传输的客户端
4 ERROR 过滤器
他是在其他过滤器发生错误调用的
2 zuul 采取动态读取,编译和运行,过滤器之间不相互通讯通过 RequetContext 对象共享数据 每个请求都会创建一个 RequestCOntext对象
zuul 过滤器的几个关键特性
1 type 过滤器的类型 post error PRE RouTINg
2 Execution Order (执行顺序),Order的值越小,越先执行
3 Crteria( 标准) Filter 执行所需条件
4 Action(行动) 如果符合执行条件,该图来自Zuul光放文档
9.3 zuul 搭建
9.3.1 搭建 Zuul 服务
1 依赖
1 父类依赖用1.5版本的
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent>
2 其他依赖
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 引入zuul依赖 , 它依赖了spring-boot-starter-actuator/spring-boot-starter-hystrix/spring-boot-starter-ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> </dependencies>
2 启动类
@EnableZuulProxy
eurekaserver
微服务都需要eureka
3 配置
配置 完端口,注册到eruek 地址以后在配置
zuul: routes: hiapi: path: /hiapi/** serviceId: eureka-client ribbonapi: path: /ribbonapi/** serviceId: eureka-ribbon-client feigenapi: path: /feignapi/** url : localhost:8080
rooutes:(下边是地址)
path
zuul 地址后跟的地址
serviceId
对应的eurekaClient 服务器名称
url
直接指向某个服务器
还可以 做自己维护的负载均衡就是指向自己的几个服务器 自行选择
9.3.2 在Zuul生配置API接口版本号
配置:
zuul.prefix: /lv
每次调用的时候要在接口前 打lv
9.3.3 在 Zuul上配置熔断器
1 implement ZuulFallbackProvider 接口
1 方法
getRoute
返回服务器的名称
* 代表返回全部 切记 不好用
fallbackResponse
public ClientHttpResponse fallbackResponse() { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { return HttpStatus.OK; } @Override public int getRawStatusCode() throws IOException { return this.getStatusCode().value(); } @Override public String getStatusText() throws IOException { return this.getStatusCode().getReasonPhrase(); } @Override public void close() { } @Override public InputStream getBody() throws IOException { return new ByteArrayInputStream("\"message\":\"服务器不可用!\"".getBytes()); } @Override public HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8")); headers.setContentType(mt); return headers; } }; }
注意
1 get body 返回的主体要json格式
2 header 也是json格式
9.3.4 在Zuul上使用过滤器
1 继承 ZuulFiter 类 并注入到Spring
1 方法
1 filterType()
注入过滤器格式
pre
上边都有
post
routing
error
2 filterOrder()
过滤顺序 越小越先执行
3 shouldFilter()
是否过滤逻辑 如果true就走run方法过滤的逻辑
4 run() 具体的过滤逻辑
HttpServletRequest request = ctx.getRequest(); RequestContext ctx = RequestContext.getCurrentContext(); String token = request.getParameter("token"); if(token==null){//如果请求参数没有就不让其过 ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(500); try { ctx.getResponse().getWriter().write("queshaoziduan "); } catch (IOException e) { }
获取进来的请求有没有token参数 如果没有就设置为flase不让其往下走 并返回writer 提示
2 请求进入zuul以后 进入过滤器然后进入逻辑判断 实际开发中可以进行安全验证
9.3.4 zuul常见的使用方式
1 缺点
因为采用SpringMVC的 DispathServlet实现 采用异步阻塞模型 所以性能比Ngnix差
2 优点
zuul 使用 Neffix的组建可以无缝集成 很容实现负载均衡,智能路由 熔断器等功能 大部分都是已zuul 集群方式存在的 由于横向zuul 发展较好 所以课题通过添加实例解决性能瓶颈
3 使用方式
1 不同渠道使用不同路由
移动端用一个 web端用一个 其他端用一个 相互结合形成负载均衡
mobilie-client
zuul
eureka 集群
注册中心
web-client
zuul
eureka集群
注册中心
2 与Ngnix 和zuul 结合起来做负载聚恒
暴露外边的是Ngnix 主从热备进行Keeplive,Nginx 根据某种落雨策略 将请求发到zuul集群上 最终发到具体服务器上
client
Ngnix keepAlive(放zuul集群)
eureka集群
注册中心
第十章 配置Spring Cloud Config
10.1 Config Server 从本地读取配置文件
Config Server 可以重本地读取配置文件,也可重远处Git仓库读取,本地的将所有配置放在工程目录下 Config Server 暴露HttpAPI 接口 Config CLient通过Config Server的 HttpAPI 接口去读取配置文件
10.1.1 构建 ConfigServer端
1 依赖
<!--别的父类有版本冲突问题--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Edgware.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </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> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
2 配置
spring: #配置本地仓库 profiles: active: native cloud: config: server: native: search-locations: classpath:shared/
注意: shared文件下的文件格式必须是 要调用客户端的名称-dev(或者其他格式).yml
3 启动类
@EnableConfigServer
10.1.2 构建SpringConfig Client
1 依赖
<!--配置中心的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
2 启动类
不需要添加
3 配置
注意: 启动类一定要用 boostrap.yml 因为bootstrap优先级比较高
spring: application: #项目文件名必须要跟配置server下的配置文件前缀相同 比如当前配置server文件就为 db-service-dev 因为下边选的是dev name: db-service cloud: config: profile: dev uri: http://localhost:8769
第十一章 服务链路追踪 Spring Cloud Sleuth
11.1 为什么要用Spring Cloud Sleuth
因为 微服务中一个方法可能穿插多个服务 所以如果不进行追踪很难判断是哪里有问题
11.2 基本术语
采用Googer的开元项目Dapper专业术语
1 Span (跨度)基本工作单元
发送一个远程调度任务就产生一个Span,Span是用一个64位唯一标示的 包含了 摘要 时间错 及进程id
2 Trace(追踪)
由一系列的span组成 树状结构 请求一个API接口 这个API接口调用微服务单元 调用每一个单元都会产生一个Span 这些Span组成 Trace
3 Annotation(注释)用于记录事件,一些核心注解用于定义一个请求的开始和结束
1 cs-Client Sent 客户端发送一个请求,这里注解描述Span的开始
2 sr-Server Received 服务端接受请求并开始处理 如果用sr-cs时间 便得到了网络的传输事件
3 ss ss Server Sent 服务器处理完请求完成的 ss-sr事件就是服务其请求的事件
4 cr Client Received 客户端接收相应 Span结束 cr-cs便是整个请求的事件
11.3 案例讲解
11.3.1构建 Zipkin Server