赞
踩
一种架构模式/风格,提倡将单一的应用程序划分为一组小的服务,服务运行在自己的进程,之间相互协作完成最终服务
解决微服务四大问题:服务治理
服务很多,客户端怎么访问
服务之间如何通信
服务怎么管理
服务出现重大故障时怎么办
设计原则:
单一职责:每个服务独立,有界限的工作,只关注自己的业务,做到高内聚
服务自治:独立开发、测试、构建、部署和运行,与其他服务解耦
轻量级通信:服务之间的调用是轻量级的,并且能够跨平台、跨语言;如RESTFUL风格和利用消息队列通信
粒度进化:服务的粒度随着业务和用户的发展而进化
解决方案:
SpringCloud + NetFlix:一站式解决方案
SpringCloud + Alibaba:一站式;精简SpringCloud + NetFlix
Apache Dubbo + Zookeeper:半自动,需要整合各部分
没有API,需整合第三方
Dubbo:RPC通信
Zookeeper:注册与发现;下载一个安装包,启动服务器端server即可
借助第三方
CAP:对数据的关注
consistency-强一致性:并发场景下数据在每个节点/系统中必须一致
Availability-可用性:系统对外提供服务必须一直处于可用状态,在任何故障下,客户端都能在合理时间下获得服务端非错误的响应
Partiton tolerance-分区容错性:遇到任何网络分区(不同节点分布在不同的子网络中)故障,系统仍能对外提供服务
一个分布式系统最多只能同时满足CP或AP:因为网络总是不可靠的:当网络故障时,不能对A系统和B系统进行数据同步,即不满足P,而AB是可访问的,但它们像单机系统而非分布式;所以P必须满足;当满足P时,需要等待数据同步,在此期间不能让被同步的系统被外部访问,否则数据不一致,因此满足CP;否则为了让系统能被访问,只能牺牲C,此时满足AP
基于SpringBoot的一套微服务解决方案,组件及对应解决方案(基本来自Netfix)包括:
Spring + Alibaba:
官网https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md;https://spring.io/projects/spring-cloud-alibaba
引入依赖(父pom.xml):具体配套的各个组件版本参考官网推荐
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-alibaba-dependencies</artifactId>
- <version>2.1.0.RELEASE</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- <!-- 老版本:H版
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-dependencies</artifactId>
- <version>Hoxton.SR1</version> <type>pom</type>
- <scope>import</scope>
- </dependency>
- -->
主要功能:
服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway,Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控
服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持
分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新
消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力
分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题
阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据
分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行
阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道
组件:
Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定
Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台
RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务
Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架
Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案
Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据
Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时任务调度服务
Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道
父module:
- <groupId>
- <artifactId>
- <version>
- <package>pom</package>
-
- <子moudule列表;在父module上右键,新建子module后此列表自动生成 -->
- <module>
-
- <!-- 统一版本管理 -->
- <projecties>
- <projcet.build.sourceEncoding>UTF-8
- <maven.compiler.source>1.8
- <maven.compiler.target>1.8
- <junit.version>
- <log4j.version>
- <lombok.version>
- <mysql.version>
- <druid.version>
- <mybatis.spring.boot.version>
- </projecties>
-
- <!-- 子模块继承,版本控制 -->
- <dependencyManagement>
- <dependencies>
- <!-- 一依赖列表,每个依赖包含了gav(groupId,artifactId,version) -->
- <dependency>...
- <dependencies>
- <dependencyManagement>
子module:
子module依次向上查找直到denpendencyManagement中的依赖;子项目声明了相同的依赖且未声明版本,则从父module继承而来并引入(父module只声明,不引入);声明了版本则使用自己的而不继承
服务提供者、消费者属于子module
新建N个服务提供者Client-Service Provider和服务消费者Client-Service Consumer的module;子pom引入需要的依赖
专属application.yml配置:
主流配置:基本和单体项目的yml文件配置相同,如端口号,应用名称(此时成为微服务名称),数据源,mybatis配置
集成不同的组件的配置
编写业务:Server一般包含了所有MVC模块,而Client一般做服务的调用,可能仅存在Controller层,配合RestTemplate(@Bean引入)简单粗暴死板调用服务接口
测试:Maven中可以跳过单元测试,取消勾选lifecycle中的test模块(闪电图标)以减少多个微服务启动的时长;开发环境开启(正式环境不能开启)热部署提高开发效率
采用CS架构设计,即包含组件Server和Client;Server是服务器,作为服务注册中心Registry提供微服务Client注册,监控各个Client是否正常运行;服务节点信息存储于服务注册表;Client客户端连接Registry实现RPC远程服务调用;注册后的Client默认30秒每次向Server发送心跳,默认3个心跳周期内未检测到节点的心跳后移除该服务节点;注重AP;已停更
自我保护机制:用来实现高可用
默认情况Server在一定时间内未接收Client实例的心跳时(微服务不可用),会注销该实例;但通常这不是Client有问题,而很可能是因为Server与Client之间网络不通或延迟等故障,因此默认3个心跳周期内开启自动保护机制,即保护模式用于Server与Client存在网络分区的场景下的自我保护
保护模式:Server尝试保护服务注册表中的信息,不清除其中的数据即不注销任何微服务
编写module的引入依赖spring-cloud-starter-netflix-eureka-server;编写yml配置;无需业务实现;启动类开启@EnableEurekaServer
Server集群:RPC最核心问题是是否高可用(AP);因此搭建多个注册中心实现负载均衡和故障容错;集群Server需要互相注册,相互守望
- server:
- port: 7001 # 假设端口7001;集群则新建类似module,如7002
-
- eureka:
- instance:
- hostname: myServer7001.com # 服务器名称;
- # 集群时因为module都在一台机器上,所以需要修改post文件,给localhost起多个别名,如myServer7002.com
- client:
- register-with-eureka: false # 是否向Registry注册本服务
- fetch-registry: false # 是否去Registry中获取其他服务的地址
- service-url:
- defaultZone: http://${euraka.instance.hostname}:${server.port}/eureka/ # 与本Server交互的地址,即http://myServer:7001/euraka/
- # 集群版需要相互注册,互相守望
- # defaultZone: http://myServer7002.com/euraka/
-
- server:
- enable-self-preservation: false # 关闭默认开启的自我保护机制
- eviction-interval-timer-in-ms: 2000 # 多少时间后注销服务
访问http://myServer7001.com:7001或http://localhost:7001,看到Spring Eureka界面;集群版也可这么访问7002,且7001页面的DS Replicas列表显示7002,7002上显示7001
- server:
- port: 8001 # 假设端口8001;提供了服务user/get
-
- spring:
- application:
- name: cloud-XXX-service # 服务名称,服务注册与发现的依据
- datasource: # 数据源配置
-
- eureka:
- client:
- register-with-eureka: true
- fetch-registry: true
- service-url:
- defaultZone: http://myServer:7001/euraka/ # 服务注册地址
- # Server集群版:注册到每一个Server
- # defaultZone: http://myServer7001.com:7001/eureka,http://myServer7002.com:7002/eureka
-
- # 可选配置,服务信息完善,显示主机ip等;需要导入web和actuator依赖
- instance:
- instance-id: myServer8001
- prefer-ip-address: true # 访问路径显示ip
- lease-renewal-interval-in-seconds: 30 # 向Server发送心跳的频率,默认30s
- lease-expiration-dutation-in-seconds: 90 # Server收到最后一次心跳后等待下一次心跳的最大时间,默认90s;超时则注销服务
-
- mybatis: # 其他配置
- @Resource
- private DiscoveryClient discoveryClient;
- public Object discovery() {
- List<String> services = discoveryClient.getServices(); // 注意别导错包
- List<ServiceInstance> instances = discoveryClient.getInstances("服务名称");
- }
分布式协调工具,可以实现服务注册与发现功能;引入依赖spring-cloud-starter-zookeeper-discovery;Server不用自己编写module,而是直接启动安装好的Zookeeper客户端;启动类上使用@EnableDiscoveryClient;注重CP
yml配置:
- server:
- port: 8001
-
- spring:
- application:
- name: cloud-XXX-service # 服务名称,服务注册与发现的依据
- cloud:
- zookeeper:
- connect-string: ip port # zookeeper服务器/注册中心所在机器IP;集群版为IP port列表
没有自我保护机制;注重CP;服务节点是临时的,重启后serviceId变化
- server:
- port: 8001
-
- spring:
- application:
- name: cloud-XXX-service # 服务名称,服务注册与发现的依据
- cloud:
- consule:
- host: localhost
- port: 7001
- discovery:
- service-name: ${spring.application.name}
Netflix开源项目;一套客户端,负载均衡工具,提供负载均衡算法和服务调用;客户端提供一系列完善的配置项,如连接超时、重试;配置文件罗列所有后的机器,Ribbon帮助自动基于某种规则去连接某个机器
LoadBalance:LB,分为进程内式的本地负载均衡,在客户端实现;和Ngnix等也可以实现的集中式负载均衡,在服务器端实现
流程:先从集群的Server中选择负载较少的;再根据指定的策略从该Server的服务注册表中选择合适的服务;策略包括轮询,随机,权重(根据响应时间加权),重试等
IRule:核心组件,策略算法规则接口RoundRobinRule轮询,RandomRule随机,RetryRule重试以及其他复合算法实现,:
默认先使用轮询,失败后在一定时间内重试
使用规则或替换默认轮询规则:编写配置类并@Bean注入IRule;官方规定不能放在@ComponentScan扫描包及子包下,否则会被所有Ribbon客户端共享,达不到特殊定制的目的;启动类@RibbonClient(name="服务名", configuration=配置类.class)
轮询:请求总数与服务总数求余,余数就是服务的索引;getInstances()获取的就是服务实例集合List< ServiceInstance>
算法原理与源码:
新版本依赖spring-cload-starter-netflix-eureka-client已经包含spring-cloud-starter-netflix-ribbon
Feign:轻量级声明式WebService客户端,使编写Web服务客户端变得简单;即改善Ribbon+RestTemplate模式下的不够灵活的RestTemplate对Http请求的封装,用Feign帮助定义和实现依赖的服务的接口并用注解@Feign方式配置
在Consumer模块中用Feign的注解@FeignClient(value="微服务名称")来定义一个接口,调用接口中方法就调用了Provider服务
启动类上@EnableFeignClients激活Feign
OpenFeign:SpingCloud在Feign基础上进行封装,使其支持SpringMVC的注解和HttpMessagerConverters;把@GetMapping()等位于Controller层的注解复制到Server层接口的方法上去,以标识去Provider中查找对应调用的方法;Controller开发不变
超时控制:Provider中服务执行时间与客户端调用该服务愿意等待执行结果的时间约定,OpenFeign默认1秒:超时控制在配置文件中配置ribbon-Readtimeout和ConnectTimeout
日志监控:获取服务执行的具体情况;配置文件中配置logging-level,;日志级别有NONE即默认不显示日志,BASIC即仅记录请求方法、URL、响应状态码和执行时间,HEADERS即包含了BASIC显示信息的请求头和响应头信息,FULL即包含了HEADERS的请求体和响应体信息,这些Bean使用@Bean方式注入
服务之间互相调用和依赖越来越多;当其中某一个服务出现故障如执行时间很久,其他服务将受到影响如一直等待,导致级联故障或服务雪崩;Hystrix即为处理分布式系统的延迟和容错的开源库,以提高系统高可用AP特性
服务降级fallback:
断路器:在某个服务故障时,通过断路器的故障监控,向服务调用者返回一个符合预期的、可处理的备选响应,而不是长时间等待或抛出调用方无法处理的异常;这类似于执行if-else的最后那个兜底else
超时,异常,服务熔断,线程池满等,都会触发服务降级
服务熔断break:达到最大服务访问量后,直接拒绝访问,即最严重的服务降级处理;当监测到异常节点的调用正常后,能够自动恢复链路调用;Hystrix的阈值默认每5秒内20次调用失败则启动熔断机制
服务限流flowlimit:严禁一窝蜂式访问,避免拥挤,采用排队有序进行,如1秒类最多允许有限个访问
构建Hystrix:
针对Provider:业务类方法上启用@HystrixCommand;启动类启动@EnableCircuitBreaker
fallbackMethod属性指定兜底方法
commandProperties属性指定规则:
简单规则如超时时间;在设置的超时时间内,正常执行方法并返回结果给调用者,超时或异常后执行兜底方法并返回
设置服务熔断相关规则:@HystrixProperties列表,属性值包括:
- @HystrixCommand(fallbackMethod = "fallbackMethod, commandProperties = {
- // 是否打开断路器
- @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
- // 请求总数阈值,即最大请求次数:在时间窗内达到了阈值,则开启服务熔断,默认20
- @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
- // 时间窗口期:断路后该时间内都会拒绝请求,过时后重新尝试接受请求,处于半开状态;即“断路器是否打开需要统计的时间内的请求数和失败数”中的时间
- @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
- // 错误百分比阈值:时间窗内异常请求占总请求次数的比例,超过时开启熔断
- @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")
- })
- public void method() {}
熔断后,再有的请求直接调用服务降级的兜底逻辑
半开状态:熔断一段时间后(默认5秒),尝试让请求进入,若依然失败,则继续熔断,否则慢慢放请求进入;重复判断-熔断-放行
针对Consumer:开发同理;启动类用@EnableHystrix,配置文件配置启用feign-hystrix-enable
HystrixDashboard:仪表盘,Hystrix服务监控图形化,可以监测请求数,失败数等各种信息;同理建立一个module,引入依赖,@EnableHystrixDashboard开启功能;被监控的服务需要引入actuatior依赖;启动后即可看到页面
JMeter:高并发压力测试软件,模拟大量并发请求
代替Zuul:路由网关;提供一种简单有效方式来对API进行路由,且基于Filter链方式提供网关基本功能,如安全、监控/指标、限流;与Zuul相反,采用非阻塞的异步/响应式API,支持链式(函数式编程);SpringCloud Gateway基于WebFlux框架实现,WebFlux底层使用了高性能的Reactor模式通信框架Netty
位置:外部请求进来,负载均衡后,添加一层网关,然后去请求微服务
核心:
路由:构建网关的基本模块,由id和目标url+一系列断言和过滤器组成;断言成功则匹配该路由
断言Predicate:匹配请求中请求头和请求参数等所有内容
过滤Filter:GatewayFilter实例,对被路由或路由后的请求的额外操作
搭建:开发无业务模块的Client并配置:
- server:
- port: 9001
- spring:
- application:
- name: cloud-XXX-service
- cloud:
- gateway:
- routes: # 路由,对每一个需要网关的请求
- - id: routeId # 路由id,唯一
- url: http://... # 被路由的网关地址;添加网关就相当于通过代理去访问真实的请求服务,访问此URL变成了访问9001,访问的接口为Predicates列表
- predicates:
- - Path: /user/get/** # 断言路径相匹配
- - After: # 断言在指定的时间之后
- - ... # 其他:cookie匹配,头部匹配...
- filter: # 一般使用配置类自定义过滤器
-
- - id:...
- ...
-
- discovery:
- locator:
- enabled: true # 开启动态路由功能,利用微服务名而不是URL进行路由
-
- # 另一种路由方式是硬编写配置类并注入RouteLocator,它的方法实现是链式
- spring:
- applicaiton:
- name: cloud-config-center
- cloud:
- config:
- server:
- git:
- url: git@github.com... # 多个存储在git仓库上的不同环境的配置文件
- search-paths:# 文件所在目录
- label: master
- eureka:
- client:
- ...
替代Eureka做服务注册中心;替代ConfigServer做服务配置中心;自动支持负载均衡(nacos-discovery包下可看到集成了netflix-ribbon);支持AP和CP的切换
安装:官网下载后,直接启动;验证安装是否成功:访问localhost:8848/nacos,账号密码默认nacos;项目总依赖spring-cloud-alibaba-dependencies
服务管理:
编写module,引入nacos-discovery依赖
yml配置:nacos注册地址为服务发现中心即localhost:8848,可省略服务消费者配置消费访问的服务提供者名称
启动类配置;业务编写;。。。最终启动此服务,在服务管理-服务列表中可看到此服务
详细参看官网:https://spring.io/projects/spring-cloud-alibaba,选择某个版本后的Reference Doc即查看文档
配置管理:
编写module;编写bootstrap.yml,如配置与discovery同级的config,其下的server-addr为配置中心地址,file-extension指定配置格式,一般都为yaml即git上的配置文件;编写application.yml,如spring-profile-active激活不同的环境
nacos界面配置列表配置服务;参考官网
集群管理:
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。