• SpringCloud搭建保姆级教程


    一、搭建服务注册与发现中⼼

    使⽤Spring Cloud Netflix 中的 Eureka 搭建服务注册与发现中⼼

    1、创建SpringBoot应用添加依赖

    1、spring web
    2、eureka server

    2、配置服务注册与发现中⼼

    复制代码
    ## 设置服务注册与发现中⼼的端⼝
    server:
      port: 8761
    ## 在微服务架构中,服务注册中⼼是通过服务应⽤的名称来区分每个服务的
    ## 我们在创建每个服务之后,指定当前服务的 应⽤名/项⽬名
    spring:
      application: null
      name: service-eureka
    eureka:
      client:
        ## ip 就是服务注册中⼼服务器的ip,port 就是服务注册与发现中⼼设置的port
        service-url:
          defaultZone: 'http://192.168.54.59:8761/eureka'
        ## 设置服务注册与发现中⼼是否为为集群搭建(如果为集群模式,多个eureka节点之间需要相互注册)
        register-with-eureka: false
         ## 设置服务注册与发现中是否作为服务进⾏注册
        fetch-registry: false
    复制代码

    3、在启动类添加@EnableEurekaServer注解

    复制代码
    @SpringBootApplication
    @EnableEurekaServer
    public class ServiceEurekaApplication {
        public static void main(String[] args) {
            SpringApplication.run(ServiceEurekaApplication.class, args);
        }
    }
    复制代码

    4、运⾏及访问

    二、服务注册

    创建保存订单的服务(order-add)注册到服务注册与发现中⼼

    1、创建SpringBoot应⽤

    创建spring boot应⽤,完成功能开发

    2、注册服务

    将能够完成特定业务的SpringBoot应⽤作为服务提供者,注册到服务注册与发现中⼼

    2.1、添加依赖eureka-server

    
     org.springframework.cloud
     spring-cloud-starter-netflix-eureka-server
    

    2.2、配置application.yml

    复制代码
    server:
      port: 9001
    ## 当前应⽤名会作为服务唯⼀标识注册到eureka
    spring:
      application:
        name: order-add
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: 'jdbc:mysql://localhost:3306/db_2010_sc?characterEncoding=utf-8'
        username: root
        password: admin123
    mybatis:
      mapper-locations: 'classpath:mappers/*'
      type-aliases-package: com.qfedu.order.beans
    ## 配置Eureka服务注册与发现中⼼的地址
    eureka:
      client: 
          service-url:
            defaultZone: 'http://localhost:8761/eureka'
    复制代码

    2.3、在当前服务应⽤的启动类添加 @EnableEurekaClient 注解

    复制代码
    @SpringBootApplication
    @MapperScan("com.qfedu.order.dao")
    @EnableEurekaClient
    public class OrderAddApplication {
        public static void main(String[] args) {
            SpringApplication.run(OrderAddApplication.class, args);
        }
    }
    复制代码

    三、服务发现-Ribbon

    服务消费者(api-order-add)通过eureka查找服务提供者(order-add),通过服务调⽤组件调⽤提供者
    • eureka server
    • ribbon

    1、基础配置

    Ribbon客户端已经停更进维啦

    1.1、创建SpringBoot应⽤,添加依赖 

    • eureka server
    • ribbon

    1.2、配置application.yml

    复制代码
    server:
      port: 8001
    spring:
      application: 
        name: api-order-add
    eureka:
      client: 
        service-url: 
            defaultZone: 'http://localhost:8761/eureka'
    复制代码

    1.3、在启动类添加 @EnableDiscoveryClient注解 

    复制代码
    @SpringBootApplication
    @EnableDiscoveryClient
    public class ApiOrderAddApplication {
        public static void main(String[] args) {
            SpringApplication.run(ApiOrderAddApplication.class, args);
        }
    }
    复制代码

    2、服务调⽤

    2.1、配置RestTemplate

    复制代码
    @Configuration
    public class AppConfig {
        @LoadBalanced //启⽤Ribbon(负载均衡)
        @Bean
         public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    }
    复制代码

    2.2、在Service中注⼊RestTemplate对象调⽤服务

    复制代码
    @Service
    public class OrderAddServiceImpl implements OrderAddService {
        @Autowired
        private RestTemplate restTemplate;
        @Override
        public ResultVO saveOrder(Order order) {
            //1. 调⽤ order-add服务进⾏保存
            ResultVO vo = restTemplate.postForObject("http://order-add/order/add", order, ResultVO.class);
            //2. 调⽤ orderitem-add 保存订单快照
            //3. 调⽤ stock-update 修改商品库存
            //4. 调⽤ shopcart-del 删除购物⻋记录
            return null;
        }
    }
    复制代码

    3、Ribbon服务调⽤说明

    @LoadBalanced注解是Ribbon的⼊⼝,在RestTemplate对象上添加此注解之后,再使
    ⽤RestTemplate发送REST请求的时候,就可以通过Ribbon根据服务名称从Eureka中查
    找服务对应的访问地址列表,再根据负载均衡策略(默认轮询)选择其中的⼀个,然后
    完成服务的调⽤
    • 获取服务列表
    • 根据负载均衡策略选择服务
    • 完成服务调⽤

    四、基于Ribbon进⾏服务调⽤的参数传递

    1、RestTemplate发送调⽤请求的⽅法

    SpringCloud的服务调⽤是基于REST的,因此当服务提供者规定了请求的⽅式,服务消
    费者必须发送对应⽅式的请求才能完成服务的调⽤,RestTemplate提供了多个⽅法⽤于
    发送不同形式的请求。
    复制代码
    //post⽅式请求
    restTemplate.postForObject();
    //get⽅式请求
    restTemplate.getForObject();
    //delete⽅式请求
    restTemplate.delete();
    //put⽅式请求
    restTemplate.put();
    复制代码

    2、put/post请求传参

    1、服务消费者请求传参
    //参数1:访问服务的url
    //参数2:传递的对象参数
    //参数3:指定服务提供者返回的数据类型
    ResultVO vo = restTemplate.postForObject("http://order-add/order/add",order, ResultVO.class);

    2、服务提供者接收参数

    @PostMapping("/add")
    public ResultVO addOrder(@RequestBody Order order){
       return orderService.saveOrder(order);
    }

    3、get请求传参

    1、服务消费者请求传参 

    String userId = order.getUserId();
    ResultVO vo = restTemplate.getForObject("http://order-add/order/add?userId="+userId, ResultVO.class);

    2、服务提供者接收参数 

    复制代码
    @GetMapping("/add")
    public ResultVO addOrder(Order order){
        return orderService.saveOrder(order);
    }
    @GetMapping("/add")
    public ResultVO addOrder(String userId){
        //return orderService.saveOrder(order);
    }
    复制代码

    五、服务发现-Feign

    1、基础配置

    1.1、创建SpringBoot应⽤,添加依赖

    spring web
    eureka server
    OpenFeign

    1.2、配置application.yml

    复制代码
    server:
      port: 8002
    spring:
      application:
        name: api-order-add-feign
    eureka:
      client:
        service-url:
          defaultZone: 'http://localhost:8761/eureka'
    复制代码

    1.3、在启动类添加注解

    复制代码
    @SpringBootApplication
    @EnableDiscoveryClient //声明为服务消费者
    @EnableFeignClients //声明启⽤feign客户端
    public class ApiOrderAddFeignApplication {
        public static void main(String[] args) {
            SpringApplication.run(ApiOrderAddFeignApplication.class, args);
        }
    }
    复制代码

    2、服务调⽤

    使⽤Feign进⾏服务调⽤的时候,需要⼿动创建⼀个服务访问客户端(接⼝)

    2.1、创建Feign客户端

    @FeignClient("order-add")
    public interface OrderAddClient {
        @PostMapping("order/add")
         public ResultVO addOrder(Order order);
    }

    2.2、使⽤Feign客户端调⽤服务

    复制代码
    @Service
    public class OrderAddServiceImpl implements OrderAddService {
        @Autowired
        private OrderAddClient orderAddClient;
        @Override
        public ResultVO saveOrder(Order order) {
            //1. 调⽤ order-add服务进⾏保存
            ResultVO vo = orderAddClient.addOrder(order);
            //2. 调⽤ orderitem-add 保存订单快照
            //3. 调⽤ stock-update 修改商品库存
            //4. 调⽤ shopcart-del 删除购物⻋记录
            return vo;
        }
    }
    复制代码

    3、Feign传参

    3.1、POST请求

    1、通过请求体传递对象

    服务提供者
    @PostMapping("/add")
    public ResultVO addOrder(@RequestBody Order order){
        System.out.println("-------------------order-add");
        System.out.println(order);
        return orderService.saveOrder(order);
    }
    服务消费者(Feign客户端)
    @FeignClient("order-add")
    public interface OrderAddClient {
        @PostMapping("order/add")
         public ResultVO addOrder(Order order);
    }

    2、通过请求⾏传参

    服务提供者
    复制代码
    @PostMapping("/add")
    public ResultVO addOrder(@RequestBody Order order,String str){
        System.out.println("-------------------order-add");
        System.out.println(order);
        System.out.println(str);
        return orderService.saveOrder(order);
    }
    复制代码
    服务消费者(Feign客户端)
    //1.对⽤POST请求调⽤服务,Feign客户端的⽅法参数默认为body传值(body只能有⼀个值)
    //2.如果有多个参数,则需要通过@RequestParam声明参数为请求⾏传值
    @PostMapping("order/add")
    public ResultVO addOrder(Order order,@RequestParam("str") String str);

    3、Get请求

    Get请求调⽤服务,只能通过url传参在Feign客户端的⽅法中,如果不指定参数的传值⽅式,则默认为body传参,Get请求也不例外;
    因此对于get请求传递参数,必须通过@RequestParam注解声明

     

    服务提供者
    @GetMapping("/get")
    public Order addOrder(String orderId){
        return new Order();
    }
    服务消费者(Feign客户端)
    @GetMapping("order/get")
    public Order getOrder(@RequestParam("orderId") String orderId);

    六、服务注册与发现中⼼的可靠性和安全性

    1、可靠性

    在微服务架构系统中,服务消费者是通过服务注册与发现中⼼发现服务、调⽤服务的,
    服务注册与发现中⼼服务器⼀旦挂掉,将会导致整个微服务架构系统的崩溃,如何保证
    Eureka的可靠性呢?
    • 使⽤eureka集群
    Eureka集群搭建
    相互注册、相互发现
    复制代码
    ## 设置服务注册与发现中⼼的端⼝
    server:
      port: 8761
    ## 在微服务架构中,服务注册中⼼是通过服务应⽤的名称来区分每个服务的
    ## 我们在创建每个服务之后,指定当前服务的 应⽤名/项⽬名
    spring:
      application:
        name: service-eureka
    eureka:
      client:
        ## 设置服务注册与发现中⼼是否为集群搭建
        register-with-eureka: true
        ## 设置服务注册与发现中是否作为服务进⾏注册
        fetch-registry: true
        ## ip 就是服务注册中⼼服务器的ip
        ## port 就是服务注册与发现中⼼设置的port
        service-url:
          defaultZone: 'http://192.168.54.10:8761/eureka'
        
    复制代码

    2、安全性

    当完成Eureka的搭建之后,只要知道ip和port就可以随意的注册服务、调⽤服务,这是
    不安全的,我们可以通过设置帐号和密码来限制服务的注册及发现。
    • 在eureka中整合Spring Security安全框架实现帐号和密码验证

    2.1、添加SpringSecurity的依赖

    
     >org.springframework.boot
     >spring-boot-starter-security
    </dependency>

    2.2、设置访问eureka的帐号和密码

    spring:
      security:
        user:
          name: zhangsan
          password: 123456

    2.3、配置Spring Security

    复制代码
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
         protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable();
            // 设置当前服务器的所有请求都要使⽤spring security的认证
            http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
        }
    }
    复制代码

    2.4、服务提供者和服务消费者连接到注册中⼼都要帐号和密码

    eureka:
      client:
        service-url:
          defaultZone: 'http://zhangsan:123456@localhost:8761/eureka'

    七、熔断器-Hystrix

    服务故障的雪崩效应:当A服务调⽤B服务时,由于B服务的故障导致A服务处于阻塞状态,当量的请求可能会导致A服务因资源耗尽⽽出现故障。
    为了解决服务故障的雪崩效应,出现了熔断器模型。

    1、熔断器介绍

    熔断器作⽤:
    1、服务降级 :⽤户请求A服务,A服务调⽤B服务,当B服务出现故障或者在特定的时间段内
    不能给A服务响应,为了避免A服务因等待B服务⽽产⽣阻塞,A服务就不等B服务的结果
    了,直接给⽤户⼀个降级响应
    2、服务熔断 :⽤户请求A服务,A服务调⽤B服务,当B服务出现故障的频率过⾼达到特定阈
    值(5s 20次)时,当⽤户再请求A服务时,A服务将不再调⽤B服务,直接给⽤户⼀个降
    级响应

    2、熔断器的原理

    3、基于Ribbon服务调⽤的熔断器使⽤

    3.1、服务消费者的服务降级

    1、添加熔断器依赖 hystrix

    
     org.springframework.cloud
     spring-cloud-starter-netflix-hystrix
    

    2、在启动类添加 @EnableHystrix 注解

    复制代码
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableHystrix
    public class ApiOrderAddApplication {
        public static void main(String[] args) {
            SpringApplication.run(ApiOrderAddApplication.class, args);
        }
    }
    复制代码

    3、在调⽤服务提供者的业务处理⽅法中,进⾏降级配置

    复制代码
    @Service
    public class OrderAddServiceImpl implements OrderAddService {
       @Autowired
       private RestTemplate restTemplate;
       @HystrixCommand(fallbackMethod ="fallbackSaveOrder",commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
          }
       )
       public ResultVO saveOrder(Order order) {
          //1. 调⽤ order-add服务进⾏保存
          //参数1:访问服务的url
          //参数2:传递的对象参数
          //参数3:指定服务提供者返回的数据类型
          ResultVO vo = restTemplate.postForObject("http://order-add/order/add",order, ResultVO.class);
          System.out.println(vo);
          return vo;
      }
      /**
       * 降级⽅法:与业务⽅法拥有相同的参数和返回值
       * @return
       */
      public ResultVO fallbackSaveOrder(Order order){
          return ResultVO.fail("⽹络异常,请重试!",null);
      }
    }
    复制代码

    3.2、服务提供者的服务降级

    1、配置步骤⼀致
    2、服务提供者接⼝降级
    复制代码
    @RestController
    @RequestMapping("/order")
    public class OrderController {
       @Autowired
       private OrderService orderService;
       @HystrixCommand(fallbackMethod ="fallbackAddOrder",commandProperties = {
          @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
          }
       )
       @PostMapping("/add")
       public ResultVO addOrder(@RequestBody Order order){
          System.out.println("-------------------order-add");
          System.out.println(order);
          try {
              Thread.sleep(5000);
          }
          catch (InterruptedException e) {
              e.printStackTrace();
          }
          return orderService.saveOrder(order);
      }
      public ResultVO fallbackAddOrder(@RequestBody Order order){
          System.out.println("-------------------order-add--fallback");
          return ResultVO.fail("订单保存失败!",null);
      }
    }
    复制代码

    1、服务熔断配置

    熔断器状态:闭合、打开、半开
    服务熔断配置
    复制代码
      @HystrixCommand(fallbackMethod ="fallbackSaveOrder",commandProperties = {
        @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000"),
         @HystrixProperty(name="circuitBreaker.enabled",value="true"),//启⽤服务熔断
        @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="10000"),//时间
        @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="10"),//请求次数
        @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="50"),//服务错误率
        }
      )
      public ResultVO saveOrder(Order order) {
        //1. 调⽤ order-add服务进⾏保存
        ResultVO vo = restTemplate.postForObject("http://orderadd/order/add", order, ResultVO.class);
        System.out.println(vo);
        return vo;
      }
      /**
      * 降级⽅法:与业务⽅法拥有相同的参数和返回值
      * @return
      */
      public ResultVO fallbackSaveOrder(Order order){
        return ResultVO.fail("⽹络异常,请重试!",null);
      }
    复制代码
    服务熔断:当⽤户请求服务A,服务A调⽤服务B时,如果服务B的故障率达到特定的
    阈值时,熔断器就会被打开⼀个时间周期(默认5s,可⾃定义),在这个时间周期
    内如果⽤户请求服务A,服务A将不再调⽤服务B,⽽是直接响应降级服务。

    4、基于Feign服务调⽤的熔断器使⽤

    Feign是基于Ribbon和Hystrix的封装

    4.1、Feign中的熔断器使⽤

    1、添加依赖(SpringBoot 2.3.11 、Spring Cloud H)

    复制代码
    
       org.springframework.boot
       spring-boot-starter-parent
       2.3.11.RELEASE
        
    
    
       1.8
       Hoxton.SR11
    
    复制代码
    
         org.springframework.cloud
         spring-cloud-starter-netflix-hystrix
    

    2、在application.yml启⽤熔断器机制

    feign:
      hystrix:
        enabled: true    

    3、在启动类添加 @EnableHystrix

    复制代码
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    @EnableHystrix
    public class ApiOrderAddFeignApplication {
        public static void main(String[] args) {
            SpringApplication.run(ApiOrderAddFeignApplication.class, args);
        }
    }
    复制代码

    4、创建服务降级处理类

    5、FeignClient的服务降级类:

      5.1.必须实现Feign客户端接⼝

      5.2.必须交给Spring容器管理

    复制代码
    @Component
    public class OrderAddClientFallback implements OrderAddClient {
        public ResultVO addOrder(Order order, String str) {
            System.out.println("-------addOrder的降级服务");
            return ResultVO.fail("fail",null);
        }
        public Order getOrder(String orderId) {
            System.out.println("-------getOrder的降级服务");
            return new Order();
        }
    }
    复制代码

    6、在Feign客户端指定降级处理类

    复制代码
    @FeignClient(value = "order-add", fallback =OrderAddClientFallback.class)
    public interface OrderAddClient {
        //1.对⽤POST请求调⽤服务,Feign客户端的⽅法参数默认为body传值(body只能有⼀个值)
        //2.如果有多个参数,则需要通过@RequestParam声明参数为请求⾏传值
        @PostMapping("order/add")
        public ResultVO addOrder(Order order,@RequestParam("str") String str);
    @GetMapping(
    "order/get") public Order getOrder(@RequestParam("orderId") String orderId); }
    复制代码

    7、Service类通过Feign客户端调⽤服务

    复制代码
    @Service
    public class OrderAddServiceImpl implements OrderAddService {
        @Autowired
        private OrderAddClient orderAddClient;
        //当我们创建Feign客户端的降级类并交给Spring管理后 在Spring容器中就会出现两个OrderAddClient对象
        @Override
        public ResultVO saveOrder(Order order) {
            //1. 调⽤ order-add服务进⾏保存
            ResultVO vo = orderAddClient.addOrder(order,"测试字符串");
            Order order1 = orderAddClient.getOrder("订单编号");
            System.out.println(order1);
            return vo;
        }
    }
    复制代码

    5、Ribbon 参数配置

    复制代码
    ribbon:
      ## Ribbon建⽴连接最⼤等待时间
      ConnectTimeout: 1000
      ## 在当前服务提供者尝试连接次数
      MaxAutoRetries: 2
      ## 与服务提供者通信时间
      ReadTimeout: 5000
    
    ## 设置熔断器服务降级时间 (默认 1000)
    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 8000
    复制代码

    6、熔断器仪表盘监控

    查看各个服务的熔断器状态面板:
    • 熔断器仪表盘

    6.1、搭建熔断器仪表盘

    1、创建SpringBoot项⽬,添加依赖

    复制代码
    
       >org.springframework.boot
       >spring-boot-starter-actuator
    </dependency>
    >
       >org.springframework.boot
       >spring-boot-starter-web
    </dependency>
    >
       >org.springframework.cloud
       >spring-cloud-starter-netflix-hystrixdashboard
    </dependency>
    复制代码

    2、配置仪表盘的port和appName

    复制代码
    server:
      port: 9999
    spring:
      application:
        name: hystrix-dashboard
    hystrix:
      dashboard:
        proxy-stream-allow-list: localhost
    复制代码

    3、启动类添加 @EanbleHystrixDashboard 注解

    复制代码
    @SpringBootApplication
    @EnableHystrixDashboard
    public class HystrixDashboardApplication {
        public static void main(String[] args) {
            SpringApplication.run(HystrixDashboardApplication.class,args);
        }
    }
    复制代码

    4、访问 http://localhost:9999/hystrix

    6.2、配置使⽤了熔断器的服务可被监控

    1、添加依赖

    
         org.springframework.boot
         spring-boot-starter-actuator
    

    2、配置(给每个需要监控熔断器的项目配置)

    复制代码
    @Configuration
    public class DashBoardConfig {
         @Bean
         public ServletRegistrationBean getServletRegistrationBean(){
            HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
            ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
            registrationBean.setName("HystrixMetricsStreamServlet");
            registrationBean.setLoadOnStartup(1);
            registrationBean.addUrlMappings("/hystrix.stream");
            return registrationBean;
        }
    }
    复制代码

    3、查看指定服务的熔断器⼯作参数

     

     

  • 相关阅读:
    浅析kubernetes中client-go structure01
    ubuntu16.04修改静态ip
    Java的jmap命令使用详解
    【scikit-learn基础】--『监督学习』之 空间聚类
    5分钟NLP:Python文本生成的Beam Search解码
    Leetcode 01-算法入门与数组-①数据结构与算法简介
    【面试心得】系统调用
    VL36-状态机-重叠序列检测;设计一个状态机,用来检测序列1011.
    JVM学习笔记(五)内存模型
    基于SpringBoot+Netty实现即时通讯(IM)功能
  • 原文地址:https://www.cnblogs.com/sun-10387834/p/17717610.html