• 22-07-20 西安 SpringCloud(01)


    微服务与分布式、集群

    1.微服务理论

    独立应用变成一套小服务,每一个都运行在自己的进程内(容器) 独立业务能力 独立部署 独立开发语言 独立的数据存储
    应该有一个能管理这些服务的中心

    2.分布式概念

    分布式系统是若干独立计算机的集合(多台服务器),这些计算机对于用户来说就像单个相关系统

    集群:集群指的是将几台服务器集中在一起,实现同一业务。
    集群就是很多服务器跑同一个项目

    分布式与集群
    == 分布式中的每一个节点 ==,都可以做集群。而集群并不一定就是分布式的。


    服务之间的交互可以用两种方式

    • RPC(Dubbo)

      • Socket包+自定义序列化
    • RestAPI (SpringCloud)

      • HTTP协议+JSON

    RPC是什么

    RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范,dubbo是其实现

    网络传输要求二进制,要序列化,打包(socket包)


    高并发
    工具限制(本身性能):
    Tomcat 默认配置的最大请求数是 150,也就是说同时支持 150 个并发。当某个应用拥有 250 个以上并发的时候,应考虑应用服务器的集群

    系统限制
    Windows 每个进程中的线程数不允许超过 2000
    Linux 每个进程中的线程数不允许超过 1000

    高并发衡量指标

    1. 响应时间(RT) :请求做出响应的时间,即一个http请求返回所用的时间
    2. 吞吐量: 系统在单位时间内处理请求的数量
    3. QPS、 TPS:每秒查询(请求)数、每秒事务数
    4. Apache JMeter:  模拟高并发

    高可用
    服务集群部署,数据库双主机方式

    主-备方式(Active-Standby方式)

    主-备方式即指的是一台服务器处于某种业务的激活状态(即Active状态),另一台服务器处于该业务的备用状态(即Standby状态)。

    双主机方式(Active-Active方式)

    双主机方式即指两种不同业务分别在两台服务器上互为主备状态(即Active-Standby和Standby-Active状态)


    版本选择

    • SpringBoot 2.3.6.RELEASE
    • SpringCloud   Hoxton.SR9
    • SpringCloud Alibaba  2.2.6.RELEASE

    RestTemplate远程调用

    创建工程啥的就直接省略了。因为要引入的依赖是在是多呀,大概做法是先创建一个父工程cloud-paraent,再在该父工程下创建其余的工程。

    还要安装一些插件,比如lombok,mybatisX以及一些idea中settings中的配置都省略

     1、先保证cloud-consumer-order80 可以远程调用 cloud-provider-payment8001成功。

    在消费端使用配置类配置bean对象RestTemplate

    1. @SpringBootConfiguration
    2. public class ApplicationContextConfig {
    3. @Bean
    4. public RestTemplate getRestTemplate(){
    5. return new RestTemplate();
    6. }
    7. }

    并在controller层注入使用RestTemplate,使用以下方法实现远程调用

    RestTemplate提供了多种便捷访问远程Http服务的方法

    • restTemplate.getForObject()完成查询
    • restTemplate.postForObject()完成添加

    远程调用方法需要的三个参数

       REST请求地址、请求参数、Http响应转换被转换成的对象类型。【其实看着都挺麻烦的,一会用OpenFeign替换】

    1. @RestController
    2. @Slf4j
    3. public class OrderController {
    4. public static final String PAYMENT_URL = "http://localhost:8001";
    5. @Resource
    6. private RestTemplate restTemplate;
    7. @PostMapping("/consumer/payment/create")
    8. public CommonResult create(@RequestBody Payment payment){
    9. return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment, CommonResult.class);
    10. }
    11. @GetMapping("/consumer/payment/get/{id}")
    12. public CommonResult getPayment(@PathVariable("id") Long id){
    13. return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    14. }
    15. }

    注意一个点,被远程调用的服务cloud-provider-payment8001的添加方法一定要使用@RequestBody,因为RESTAPI的风格就是http+json.


    Eureka服务注册与发现(中心)

    Eureka采用了CS的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接

    注册中心(存放服务地址相关信息(接口地址))

    Eureka Server  提供服务注册服务

    各个微服务节点通过配置启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息。

    Eureka Client  通过注册中心进行访问

    是一个Java客户端,用于简化Eureka Server的交互。

    --------

    单机Eureka的构建步骤

    IDEA生成eurekaServer端服务注册中心,也就是工程: cloud-eureka-server7001

    这个工程特殊的地在于

    1、引入以下依赖

    1. <dependency>
    2. <groupId>org.springframework.cloudgroupId>
    3. <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
    4. dependency>

    2、同时在application.yml中做如下配置,一会浏览器访问    http://localhost:7001/

    1. server:
    2. port: 7001 # eureka的服务端
    3. eureka:
    4. instance:
    5. hostname: localhost #注册中心所在的服务器地址
    6. client:
    7. register-with-eureka: false #因为我就是服务端,不需要注册到Eureka中
    8. fetchRegistry: false #我就是服务端不需要从Eureka中获取信息
    9. service-url:
    10. defaultZone: http://localhost:7001/eureka # 注册中心的访问地址

    3、在主启动类上加注解 @EnableEurekaServer

    1. @SpringBootApplication
    2. @EnableEurekaServer
    3. public class Application7001 {
    4. public static void main(String[] args) {
    5. SpringApplication.run(Application7001.class,args);
    6. }
    7. }

    此时,启动工程 cloud-eureka-server7001,在浏览器端访问   http://localhost:7001/


    在服务的提供者cloud-provider-payment8001和服务的消费者cloud-consumer-order80 中 

    都引入以下依赖,它俩都是Eurake的客户端

    1. <dependency>
    2. <groupId>org.springframework.cloudgroupId>
    3. <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
    4. dependency>

    在配置文件application.yml中加入以下配置

    提供者 cloud-provider-payment8001配置如下:

    1. eureka:
    2. client:
    3. register-with-eureka: true #8001支付微服务 是客户端需要向注册中心注册信息
    4. fetchRegistry: true #8001支付微服务 是客户端需要从注册中心获取信息
    5. service-url:
    6. defaultZone: http://localhost:7001/eureka

    消费者 cloud-consumer-order80配置如下:

    1. eureka:
    2. client:
    3. register-with-eureka: true
    4. fetchRegistry: true
    5. service-url:
    6. defaultZone: http://localhost:7001/eureka

    分别在主启动类加上注解:@EnableEurekaClient

    提供者 cloud-provider-payment8001主启动类如下:

    1. @SpringBootApplication
    2. @MapperScan(basePackages = "com.atguigu.springcloud.dao")
    3. @EnableEurekaClient
    4. public class PaymentMain8001 {
    5. public static void main(String[] args) {
    6. SpringApplication.run(PaymentMain8001.class,args);
    7. }
    8. }

    消费者 cloud-consumer-order80主启动类如下:

    1. @SpringBootApplication
    2. @EnableEurekaClient
    3. public class OrderMain80 {
    4. public static void main(String[] args) {
    5. SpringApplication.run(OrderMain80.class,args);
    6. }
    7. }

    依次启动工程 7001,8001,80

    访问:http://localhost:7001/


    Ribbon负载均衡服务调用

    Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。

    Ribbon目前也进入维护模式,未来替换方案是Spring Cloud LoadBalancer

    LB负载均衡

    将用户的请求平均分配到多个服务器上,从而达到系统的HA(高可用)。

    Ribbon的本地负载均衡客户端  VS Nginx服务端负载均衡区别:

    • Nginx是服务器负载均衡,客户端所有请求都会交给Nginxhttp的服务器,然后由nginx实现转发请求到tomcat。即负载均衡是由服务器端完成的。
    • Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用。

    集中式LB(如Nginx

    • 即在服务的消费方和提供方之间使用独立的LB设施,由该设施负责把访问请求通过某种策略转发至服务的提供方;

    进程内LB(如Ribbon

    • 将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。

    Ribbon=负载均衡+RestTemplate调用

    Ribbon在工作时分成两步:

    第一步,先选择EurekaServer,它优先选择在同一个区域内负载较少的server。

    第二步,再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。其中Ribbon提供了多种策略。比如:轮询随机和根据响应时间加权。

    总结:Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例。

    Eureka客户端自带Ribbon的依赖,所以就没必要再引入下面的ribbon依赖

    1. <dependency>
    2. <groupId>org.springframework.cloudgroupId>
    3. <artifactId>spring-cloud-starter-netflix-ribbonartifactId>
    4. dependency>

    ----------
    Ribbon核心组件IRule 

    IRule 接口及实现类如下:

    IRule:根据特定算法从服务列表中选取一个要访问的服务

    1. com.netflix.loadbalancer.RoundRobinRule 轮询,默认策略。
    2. com.netflix.loadbalancer.RandomRule  随机
    3. com.netflix.loadbalancer.RetryRule 先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务
    4. WeightedResponseTimeRule  对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择(主动处理)
    5. BestAvailableRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
    6. AvailabilityFilteringRule 先过滤掉故障实例,再选择并发较小的实例
    7. ZoneAvoidanceRule 默认规则,复合判断server所在区域的性能和server的可用性选择服务器

    如何配置负载均衡策略

    新建一个配置类,要特别注意该配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化订制的目的了。

    1. @SpringBootConfiguration
    2. public class MySelfRule {
    3. @Bean
    4. public IRule myRule(){
    5. return new RoundRobinRule();
    6. }
    7. }

    主启动类添加@RibbonClient

     在RestTemplate配置类上加注解,@LoadBalanced

    在controller层修改代码,url不再是 http://localhost:8001

    复刻8001,再生成8002的服务

    做到这些还不够,现在只有8001的提供者,我们再给他复刻出来一个8002的服务

    8001(右键复制)

    想要上面那样的效果,需要快速运行设置

    vm options: -Dserver.port=8002

     意味着服务名一样,同一个服务多个实例

    重启80服务,重新获取服务列表。

    此时再测试就达到了负载均衡轮询的效果(很帅)

    Ribbon负载均衡算法
    rest接口第几次请求数%服务器集群总数量=实际调用服务器位置下标

    每次服务重启动后rest接口计数从1开始。


    OpenFeign服务接口调用

    HttpMessageConverters消息转交器

    Feign是一个声明式的web服务客户端,Feign旨在使用编写Java Http客户端变得更容易。

    Feign内置了 Ribbon

    1、利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。

    2、与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。

    OpenFeign是Spring Cloud 在Feign的基础上支持了SpringMVC的注解,如@RequestMapping。

    引入依赖

    1. <dependency>
    2. <groupId>org.springframework.cloudgroupId>
    3. <artifactId>spring-cloud-starter-openfeignartifactId>
    4. dependency>

    在配置文件application.yml加入以下配置

    1. server:
    2. port: 80
    3. spring:
    4. application:
    5. name: cloud-consumer-feign-order80
    6. eureka:
    7. client:
    8. register-with-eureka: true
    9. fetch-registry: true
    10. service-url:
    11. defaultZone: http://localhost:7001/eureka

    在主启动类加一个注解 @EnableFeignClients,不加@EnableEurekaClient也可以吗?也可以的

    1. @SpringBootApplication
    2. @EnableEurekaClient
    3. @EnableFeignClients
    4. public class OrderFeignMain80 {
    5. public static void main(String[] args) {
    6. SpringApplication.run(OrderFeignMain80.class,args);
    7. }
    8. }

    之前使用Ribbon+RestTemplate,因为不符合编程习惯。咱还是喜欢三层架构,没有Service层浑身不爽啊,那就使用OpenFeign的方式

    在Controller层,调用service层,接着啥也不管。就是这么任性,哼。让我想起了傲娇的央视六公主,在b站的简介,就一个字。哼~

    1. @RestController
    2. public class OrderFeignController {
    3. @Resource
    4. private PaymentFeignService paymentFeignService; //调用远程的微服接口
    5. @GetMapping(value = "/consumer/payment/get/{id}")
    6. public CommonResult getPaymentById(@PathVariable("id") Long id){
    7. //远程调用
    8. return paymentFeignService.getPaymentById(id);
    9. }
    10. }

    实现方式:接口+@FeignClient

    新建PaymentFeignService接口并新增注解@FeignClient

    1. @Component
    2. @FeignClient(value = "CLOUD-PAYMENT-SERVICE") //下载注册中心的服务信息
    3. public interface PaymentFeignService {
    4. @PostMapping(value = "/payment/create")
    5. public CommonResult create(@RequestBody Payment payment);
    6. @GetMapping(value = "/payment/get/{id}")
    7. public CommonResult getPaymentById(@PathVariable("id") Long id);
    8. }

    启动服务7001,8001,8002,openFeign80 

    浏览器测试

    Feign自带负载均衡(轮询)配置项

    OpenFeign超时控制

    在服务提供者处故意暂停程序,模拟3秒的延迟

    Feign说:我只等一秒(默认等待一秒),等不到就错误渲染

     那肯定1秒是太短了呀,就要设置Feign超时时间,在application.yml中加入以下配置(顶格)

    1. ribbon:
    2.   ReadTimeout:  4000 # 读取
    3.   ConnectTimeout: 4000  # 连接

  • 相关阅读:
    MyBatis-Plus使用
    计算机毕业设计ssm房源网4c6sv系统+程序+源码+lw+远程部署
    【云原生之Docker实战】使用Docker部署excalidraw白板绘图工具
    Nginx配置动态反向代理
    前端vue实现目录锚点跳转及滚动到指定内容区域(带源码)
    Feign
    MySQL 权限分配
    6. MySQL 查询、去重、别名
    云原生大数据平台零信任网络安全实践技术稿
    混合专家模型 (MoE) 详解
  • 原文地址:https://blog.csdn.net/m0_56799642/article/details/125898340