ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringCloud学习笔记

2022-07-23 14:32:50  阅读:154  来源: 互联网

标签:服务 String SpringCloud 笔记 public 学习 eureka class cloud


1、SpringCloud基础学习

1、模块之间的调用

1、模块之间的调用使用RestTemplate类,将这个类交由Spring容器管理

RestTemplate:提供多种便捷访问远程http服务的方法,简单的restful服务模板

 @Configuration
 public class RestTemplateConfig {
 ​
     @Bean
     public RestTemplate restTemplate(){
         return new RestTemplate();
    }
 }

2、测试

  1. 生产者Controller

     @RestController
     @RequestMapping("/dept")
     public class DeptController {
     ​
         @Autowired
         private DeptService deptService;
     ​
         @GetMapping("/list")
         public String list(){
             return deptService.getDeptList().toString();
        }
     ​
         @PostMapping("/add")
         public boolean add(@RequestBody Dept dept){
             return deptService.addDept(dept);
        }
     }
  2. 消费者Controller

     @Controller
     @RequestMapping("/consumer")
     public class DeptConsumerController {
     ​
         private static final String REST_URL_PREFIX = "http://localhost:8001";
     ​
         @Autowired
         private RestTemplate restTemplate;
     ​
         // 消费者不应该有Service,而是通过RestTemplate调用生产者的接口
         @GetMapping("/depts")
         @ResponseBody
         public String getDepts(){
             String listStr = restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", String.class);
             return listStr;
        }
     ​
         @GetMapping("/add")
         @ResponseBody
         public String addDepts(){
             Dept dept = new Dept();
             dept.setName("总经办").setDatasource("test");
             Boolean isSuccess = restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
             return String.valueOf(isSuccess);
        }
     }

 

2、Eureka服务注册与发现

==注意==:本次父工程用的SpringBootSpringCloud的依赖版本如下:

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-dependencies</artifactId>
     <version>2.2.6.RELEASE</version>
     <type>pom</type>
     <scope>import</scope>
 </dependency>
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-dependencies</artifactId>
     <version>Hoxton.SR4</version>
     <type>pom</type>
     <scope>import</scope>
 </dependency>

 

Eureka包含两大组件:EurekaServer 和 EurekaClient

 

EurekaServer提供服务注册服务:每个服务启动后在EurekaServer进行注册,EurekaServer服务注册表会储存所有服务节点的信息,这些节点信息会在服务界面中直观的看到

 

EurekaClient是一个java客户端,用于简化与EurekaServer的交互,客户端也具备一个内置的、使用轮询(roud-robin)负载算法的负载均衡器。在启动应用后会EurekaServer发送心跳(默认为30秒)。如果EurekaServer在多个心跳周期内没有接到某个节点的心跳,EurekaServer会从注册表中把这个服务移除(默认90秒)

1、EurekaServer 配置

1、导入依赖

 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
 </dependency>

2、eureka配置文件配置

 server:
  port: 7001
   
 eureka:
  instance:
    hostname: localhost # eureka服务端的实例名称
  client:
    register-with-eureka: false # 是否向eureka注册中心注册自己
    fetch-registry: false # 如果为false,则表示自己为注册中心
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 注册中心的交互地址

3、在主配置类上开启自动启用eureka服务

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

 

2、EurekaClient注册服务

1、导入依赖

 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>

2、配置文件配置

 server:
  port: 8001
 ​
 eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:7001/eureka/
  instance:
     # 自定义服务名称
    instance-id: dept-provider8001
     # 访问路径是否显示ip
    prefer-ip-address: true

3、主配置类上加上@EnableEurekaServer注解

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

 

4、服务信息完善

  • 加入依赖:

     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
  • application.yml配置添加

     info:
      app.name: springcloud
      app.company: www.myspringcloud.com

 

3、Eureka自我保护机制

在自我保护模式中,Eureka Server会保护注册表中的服务信息,不再注销任何服务实例。当他收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护机制。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的实例。一句话讲解:好死不如赖活着。

可以通过 server.enable-self-preservation = false禁用掉自我保护机制,但不推荐禁用

 

4、服务发现:

1、主配置类上加上@EnableDiscoveryClient注解

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

2、使用DiscoveryClient类

 @Autowired
 private DiscoveryClient client;
 ​
 ​
 @GetMapping("/servers")
     public Object servers(){
         List<String> services = client.getServices();
         System.out.println(services);
         List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER");
         instances.forEach(i -> {
             System.out.println(i.getServiceId() + "\t" + i.getHost() + "\t" + i.getPort());
        });
         return this.client;
    }

 

5、Eureka搭建集群

项目端口为7001、7002、7003的为Eureka Server

项目端口为8001的为要注册的服务

1、项目7001配置

 server:
  port: 7001
 ​
 eureka:
  instance:
     # eureka服务实例名称
    hostname: eureka7001
  client:
    register-with-eureka: false # 不向注册中心注册自己
    fetch-registry: false # 表示自己就是注册中心
    service-url:
      # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

2、项目7002配置

 server:
  port: 7002
 ​
 eureka:
  instance:
     # eureka服务实例名称
    hostname: eureka7002
  client:
    register-with-eureka: false # 不向注册中心注册自己
    fetch-registry: false # 表示自己就是注册中心
    service-url:
      # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/

3、项目7003配置

 server:
  port: 7003
 ​
 eureka:
  instance:
     # eureka服务实例名称
    hostname: eureka7003
  client:
    register-with-eureka: false # 不向注册中心注册自己
    fetch-registry: false # 表示自己就是注册中心
    service-url:
      # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/

4、项目8001配置

 eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
     # 自定义服务名称
    instance-id: dept-provider8001
     # 访问路径是否显示ip
    prefer-ip-address: true

 

3、Ribbon负载均衡

1、Ribbon的简单使用

客户端的负载均衡,查找到可用服务实例列表,把每个请求在服务列表中轮询

1、导入jar包

 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
 </dependency>

2、RestTemplate加上@LoadBalanced注解

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

 

2、Ribbon的负载均衡算法

要使用其它的算法,则在config的配置类将IRule的实现类注入到bean容器即可,默认的是使用轮询RoundRobinRule

 

3、自定义RIbbon负载均衡算法

1、在主配置类上加上@RibbonClient(name = "服务名",configuration = 自定义算法类.class)

注意: 自定的Ribbon算法类不能放在@ComponentScan注解扫描的包及其子包下,也就是说不能放在主配置类所在的包下及其子包下

 @SpringBootApplication
 @EnableEurekaClient
 @RibbonClient(name = "服务名",configuration = MySelfRule.class)
 public class DeptConsumerApplication80 {
     public static void main(String[] args) {
         SpringApplication.run(DeptConsumerApplication80.class,args);
    }
 }

2、MySelfRule.java

 @Configuration
 public class MySelfRule {
     @Bean
     public IRule myRule(){
         return new MyRandomRule();
    }
 }

3、MyRandomRule.java

根据RandomRule.java实现的算法修改成自定义算法:每台服务在被调用5次后轮询下一台服务

 public class MyRandomRule extends AbstractLoadBalancerRule {
 ​
     // 服务被调用的次数
     private int total = 0;
     // 当前服务list的下标
     private int currentIndex = 0;
 ​
     public Server choose(ILoadBalancer lb, Object key) {
         if (lb == null) {
             return null;
        }
         Server server = null;
 ​
         while (server == null) {
             if (Thread.interrupted()) {
                 return null;
            }
             // 可用的服务列表
             List<Server> upList = lb.getReachableServers();
             // 所有服务列表
             List<Server> allList = lb.getAllServers();
 ​
             int serverCount = allList.size();
             if (serverCount == 0) {
                 return null;
            }
 ​
             // 是否被掉用5次
             if (total < 5){
                 server = upList.get(currentIndex);
                 total ++;
            } else {
                 total = 0;
                 currentIndex ++;
                 // 轮询到最后一台服务,则从头开始轮询
                 if (currentIndex >= allList.size()){
                     currentIndex = 0;
                }
            }
 ​
             if (server == null) {
                 Thread.yield();
                 continue;
            }
 ​
             if (server.isAlive()) {
                 return (server);
            }
 ​
             server = null;
             Thread.yield();
        }
 ​
         return server;
 ​
    }
     
     @Override
     public Server choose(Object key) {
         return choose(getLoadBalancer(), key);
    }
 ​
     @Override
     public void initWithNiwsConfig(IClientConfig clientConfig) {
         // TODO Auto-generated method stub
 ​
    }
 }
 ​

 

4、Feign负载均衡

什么是Feign?

Feign是一个声明式的Web服务客户端,使得编写Web服务客户端变得非常容易

使用方法:==只需要创建一个接口,在上面添加注解即可==

 

Feign继承了Ribbon,所以默认也是轮询实现客户端的负载均衡。而与Ribbon不同的是,==通过Feign只需要定义服务绑定接口且以声明式的方法==,优雅而简单的实现服务调用

1、导入jar包

 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
 </dependency>

2、在接口上使用@FeignClient(value = "服务名称")注解绑定服务名称

 @FeignClient(value = "服务名称")
 public interface DeptClientService {
     @GetMapping("/对应服务接口url")
     public String list();
 ​
     @GetMapping("/对应服务接口url")
     public String get(@PathVariable("deptNo") Integer deptNo);
 ​
     @PostMapping("/对应服务接口url")
     public boolean add(@RequestBody Dept dept);
 }

3、在主启动类上加@EnableFeignClients(basePackages = {"@FeignClient标注接口所在的包"})扫描到我们的FeignClient接口到容器

 @SpringBootApplication
 @EnableEurekaClient
 @EnableFeignClients(basePackages = {"@FeignClient所在的包"})
 public class DeptConsumerFeignApplication {
     public static void main(String[] args) {
         SpringApplication.run(DeptConsumerFeignApplication.class,args);
    }
 }

总结:Feign相当于Ribbon + RestTemplate

 

5、Hystrix断路器

微服务面临的问题:当服务与服务之间的调用中,某个服务在不可用的情况下,可能会造成请求超时、延时,但有大量的请求的时候就可能会造成服务资源紧张,从而导致服务雪崩。==而Hystrix作为断路器可以向调用方返回一个符合预期、可处理的备选响应(FallBack),而不是长时间等待或抛出调用方法处理异常。==这样保证了线程不会被长时间、不必要的占用,从而避免故障在分布式系统中的蔓延,乃至雪崩。

1、服务熔断

1、导入jar包

 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
 </dependency>

2、主启动类上加上@EnableCircuitBreaker注解,开启对hystrix的支持

 @SpringBootApplication
 @EnableEurekaClient
 @EnableDiscoveryClient
 // 启动对hystrix熔断器的支持
 @EnableCircuitBreaker
 public class DeptProviderHystrixApplication8001 {
     public static void main(String[] args) {
         SpringApplication.run(DeptProviderHystrixApplication8001.class,args);
    }
 }

3、在调用方法上加上@HystrixCommand(fallbackMethod = "当方法抛出异常时要调用的接口")

 @GetMapping("/get/{deptNo}")
 // 报错时调用/hystrixGet接口
 @HystrixCommand(fallbackMethod = "hystrixGet")
 public String get(@PathVariable("deptNo") Integer deptNo) throws JsonProcessingException {
         ObjectMapper objectMapper = new ObjectMapper();
         Dept dept = service.get(deptNo);
         // 如果结果为空,则抛出异常
         if (null == dept){
             throw new RuntimeException("该部门Id" + deptNo + "没有对应的信息");
        }
         String deptJson = objectMapper.writeValueAsString(dept);
         return deptJson;
    }
 ​
 @GetMapping("/hystrixGet")
 public String hystrixGet(@PathVariable("deptNo") Integer deptNo){
         return "没有找到部门信息";
    }

 

2、服务降级

在我们的服务不可用的时候,会调用我们Feign接口实现类的方法

1、创建我们Feign接口的处理类DeptClientServiceFallbackFactory

 @Component
 public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> {
     @Override
     public DeptClientService create(Throwable cause) {
         return new DeptClientService() {
             /**
              * 获取所有部门
              * @return
              */
             @Override
             public String list() {
                 return "系统错误!";
            }
 ​
             /**
              * 根据部门id获取部门
              * @param deptNo
              * @return
              */
             @Override
             public String get(Integer deptNo) {
                 return "系统错误!";
            }
 ​
             /**
              * 添加一个部门
              * @param dept
              * @return
              */
             @Override
             public boolean add(Dept dept) {
                 return false;
            }
        };
    }
 }

2、接口的@FeignClient(value = "服务名称",fallbackFactory = DeptClientServiceFallbackFactory.class)指定我们的处理类

 //@FeignClient(value = "SPRINGCLOUD-PROVIDER")
 @FeignClient(value = "SPRINGCLOUD-PROVIDER",fallbackFactory = DeptClientServiceFallbackFactory.class)
 public interface DeptClientService {
     @GetMapping("/list")
     public String list();
 ​
     @GetMapping("/get/{deptNo}")
     public String get(@PathVariable("deptNo") Integer deptNo);
 ​
     @PostMapping("/add")
     public boolean add(@RequestBody Dept dept);
 }

3、在application.yml配置文件中加上配置

 feign:
  hystrix:
    enabled: true # 开启熔断机制

==注意:在Feign接口的实现类上别忘记加上@Component注解==

 

 

6、服务监控Hystrix Dashboard

Hystrix提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求成功,多少失败等。

1、监控服务模块(端口9001)

1、添加依赖

 <!--hystrix-->
 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
 </dependency>
 ​
 ​
 <!--hystrix dashboard-->
 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
 </dependency>

2、主启动类上添加@EnableHystrixDashboard注解开启服务监控支持

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

2、被监控服务模块(端口8001)

1、添加依赖

 <!--actuator监控信息完善-->
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
 </dependency>
 ​
 <!--hystrix-->
 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
 </dependency>

2、主启动类添加@EnableCircuitBreaker开启熔断功能

 @SpringBootApplication
 @EnableEurekaClient
 @EnableDiscoveryClient
 // 启动对hystrix熔断器的支持
 @EnableCircuitBreaker
 public class DeptProviderHystrixApplication8001 {
     public static void main(String[] args) {
         SpringApplication.run(DeptProviderHystrixApplication8001.class,args);
    }
 }

3、application.yml配置文件配置(通过“/actuator/hystrix.stream”访问不到时)

 # hystrix dashboard服务监控访问路径
 management:
  endpoints:
    web:
      exposure:
        include: "*"

 

 

7、Zuul网关

两个主要功能:路由过滤

路由:将外部请求转发到具体的微服务实例上,实现了外部统一访问的统一入口

过滤:对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础

 

注意: Zuul服务最终会注册到Eureka

提供 = 代理 + 路由 + 过滤三大功能

1、网关模块(端口:9527)导入依赖

 <!-- eureka client-->
 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>
 ​
 <!--zuul-->
 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
 </dependency>

2、主配置类上添加@EnableZuulProxy注解

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

3、application.yml配置路由

 zuul:
  prefix: /springcloud # 所有的请求前缀都要加上才能访问
  routes:
    mydept:  # 面向服务的路由配置,此名称可以自定义
      service-id: springcloud-provider
      path: /mydept/**
  ignored-services: springcloud-provider # 不能再通过原有的服务名访问
   # 所有的原有服务名都不能访问
   # ignored-services: "*"

注意:网关模块也需要注册到eureka,配好路由后访问接口通过:http://localhost:9527/zuul前缀/服务映射名/接口路径

 

8、Config配置中心

微服务要将单体应用拆分成许多的子服务,因此系统会出现大量的服务,每个服务又都需要必要的配置信息才能运行,后期要修改配置,维护起来也不方便。所以一套集中式,动态配置管理设施必不可少。SpringCloud提供了Config Server来解决这个问题。

 

1、Config服务端(端口:3344)

1、导入依赖

 <!--springcloud config-->
 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-config-server</artifactId>
 </dependency>

2、主配置类上加上@EnableConfigServer注解

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

3、application.yml配置文件

 server:
  port: 3344
 ​
 ​
 spring:
  application:
    name: springcloud-config
  cloud:
    config:
      server:
        git:
          uri: "远程仓库地址"
          username: "用户名"
          password: "密码"
          default-label: "默认分支"

4、配置读取规则

 /{application}/{profile}[/{label}]
 /{application}-{profile}.yml
 /{label}/{application}-{profile}.yml
 /{application}-{profile}.properties
 /{label}/{application}-{profile}.properties
 ​
 ​
 {application}: 配置文件的名称
 {profile}: 配置文件的版本,例如我们开发中的 dev:开发环境版本 test:测试环境版本 release:发布环境版本
 .yml和.properties: 用于区分两种配置文件
 {label}: 表示 git 分支,默认是 master 分支
 ​
 示例:http://localhost:3344/application/dev/master
  http://localhost:3344/application-dev.yml
  http://localhost:3344/master/application-dev.yml
  http://localhost:3344/application-dev.properties
  http://localhost:3344/master/application-dev.properties

 

2、Config客户端(通过Config服务端读取远程配置,动态获取端口启动项目)

1、导入依赖

 <!--springcloud config客户端-->
 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-config</artifactId>
 </dependency>
 ​
 <!--必须要-->
 <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

2、创建bootstrap.yml,进行如下配置

 spring:
  cloud:
    config:
      name: application # 从远程仓库读取的配置文件名,注意:没有.yml后缀
      profile: dev # 配置文件版本
      label: master # 分支名
      uri: localhost:3344 # config配置中心服务端地址

==注意:application.yml:用户级别配置文件==

==bootstrap.yml:系统级别配置文件,优先级大于application.yml==

 

 

标签:服务,String,SpringCloud,笔记,public,学习,eureka,class,cloud
来源: https://www.cnblogs.com/zhouqiangshuo/p/16511967.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有