• 微服务中服务间通信


    • Nacos(服务发现/注册中心)
      • Nacos是构建以“服务”为中心的现代应用架构(微服务范式、云原生范式)的服务基础设施
      • Nacos快速实现动态服务发现、服务配置、服务元数据及流量管理,更敏捷和容易地构建、交付和管理微服务平台。
      • 常见的注册中心
        • Eureka(原生,2.0版本遇到性能瓶颈期,现已停止维护)
        • Zookeeper(支持,专业的独立产品,如Dubbo)
        • Consul(原生,采用GO语言开发)
        • Nacos(推荐使用)
      • Nacos的使用流程
        • 事先说明:假设现在A服务调用B服务的方法
          • 将A服务和B服务都在Nacos注册中心中注册
          • 根据注册中心提供的地址,A服务才可以调用B服务
          • 这里说的服务是小项目工程(maven工程)
        • 安装Nacos,注意SpringBootSpringCloudNacos的版本对应
        • 双击startup.cmd启动nacos,在浏览器中输入 http://localhost:8848/nacos
          • username: nacos
          • password: nacos
        • 尽量在外层(包含A、B服务的pom.xml)中引入依赖
          <!--服务注册-->
          <dependency>
               <groupId>org.springframework.cloud</groupId>
               <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
           </dependency>
          
        • 在要注册服务(即A、B服务,两服务都要)的配置文件中配置Nacos地址
          # Nacos服务地址
          spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
          
        • 在要注册服务(即A、B服务,两服务都要)的启动类中添加注解EnableDiscoveryClient
        • 启动服务即可在Nacos中看到
    • Feign(服务调用)
      • 尽量在外层(包含A、B服务的pom.xml)中引入依赖
        <!--服务注册-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        
      • 在调用端服务(即A服务)启动类中添加注解EnableFeignClients
      • 在调用端服务(即A服务)创建一个接口,使用注解指定调用服务名称,定义调用的方法路径
        • 添加注解FeignClient("被调用端服务名称(即B服务)")
        • 指定方法(可从被调用端控制类中复制,这样不会出错,另外注解PathVariable中需指定参数名称)
        • 示例如下
          package com.xsha.eduservice.client;
          
          import com.xsha.commonutils.R;
          import com.xsha.servicebase.exceptionhandler.MyException;
          import io.swagger.annotations.ApiOperation;
          import io.swagger.annotations.ApiParam;
          import org.springframework.cloud.openfeign.FeignClient;
          import org.springframework.stereotype.Component;
          import org.springframework.web.bind.annotation.DeleteMapping;
          import org.springframework.web.bind.annotation.PathVariable;
          
          @FeignClient("serviceB")
          @Component
          public interface VodClient {
              // 调用的路径写完整
              @ApiOperation(value = "删除视频")
              @DeleteMapping("/eduvod/video/deleteAlyVideo/{videoId}")
              public R deleteAliyunVideo(@ApiParam(name = "videoId", value = "视频ID")
                                             @PathVariable("videoId") String videoId) throws MyException;
          }
          
          
      • 最后在调用端服务(A服务)控制类(或者其他层上的类)中注入上面创建的接口即@Autowired private VodClient vodClient,现在就可以调用B服务的控制类方法了
    • Spring Cloud在接口调用上,大致会经过如下几个组件
      • 接口化请求调用 -> Feign -> Hystrix -> Ribbon -> Http Client(apache http components 或者 Okhttp)
      • 说明
        • 接口化请求调用 当调用被注解FeignClient修饰的接口时,在框架内部将请求转换成Feign的请求实例feign.Request,交由Feign框架处理
        • Feign(服务调用) 转化请求Feign是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,封装了Http调用流程
        • Hystrix(熔断器) 熔断处理机制Feign的调用关系,会被Hystrix代理拦截,对每一个Feign调用请求,Hystrix都会将其包装成HystrixCommand,
          参与Hystrix的流控和熔断规则。如果请求判断需要熔断,则Hystrix直接熔断,抛出异常或者使用FallbackFactory返回熔断Fallback结果,如果通过,
          则将调用请求传递给Ribbon组件
        • Ribbon(负载均衡) 主要是当请求传递到Ribbon之后,Ribbon会根据自身维护的服务列表、服务质量等(平均响应时间,Load)结合特定的规则,
          从列表中挑选合适的服务实例,选择好机器之后,然后将机器实例的信息请求传递给Http Client客户端,Http Client客户端来执行真正的Http接口调用
        • Http Client(客户端) 真正执行Http调用,根据上层Ribbon传递过来的请求,已经指定了服务地址,则Http Client开始执行真正的请求
    • Hystrix(熔断器)
      • 导入依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        
      • 调用端(A服务)配置文件中开启熔断器
        # 开启熔断器
        feign.hystrix.enabled=true
        # 设置熔断器超时时间,默认1000ms
        hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000
        
      • 调用端(A服务)创建上述为服务调用(VodClient)接口的实现类,并实现出错之后的功能方法
        package com.xsha.eduservice.client;
        
        import com.xsha.commonutils.R;
        import com.xsha.servicebase.exceptionhandler.MyException;
        import org.springframework.stereotype.Component;
        
        import java.util.List;
        @Component
        public class VodFileDegradeFeignClient implements VodClient {
            @Override
            public R deleteAliyunVideo(String videoId) throws MyException {
                return R.error().message("删除视频出错了!");
            }
        
            @Override
            public R deleteVideoBatch(List<String> videoList) throws MyException {
                return R.error().message("批量删除视频出错了!");
            }
        }
        
      • 在接口上注解FeignClient中添加fallback属性及值@FeignClient(name="service-vod", fallback=VodFileDegradeFeignClient.class)
      • 这时调用端(A服务)调用被调用端(B服务)的方法时,就可以根据返回值,根据需求完成更合理的接口(如抛出异常等)
        R result = vodClient.deleteAliyunVideo(videoSourceId);
        if(result.getCode() == 20001) {
            throw new MyException(20001, "删除视频失败,熔断器。。。");
        }
        
  • 相关阅读:
    Hibernate sqlserver 的对象转成 Hibernate mysql 的对象时 需注意
    将绿色版Tomcat服务添加到系统服务并设为开机运行
    进程上下文和中断上下文
    关于上、下拉电阻的总结整理
    I2C设备驱动流程
    MTK6573的LDO控制
    iomem—I/O映射方式的I/O端口和内存映射方式的I/O端口
    Linux I2C子系统分析I2C总线驱动
    Camera读取ID方法总结
    Linux 信号signal处理机制
  • 原文地址:https://www.cnblogs.com/aitiknowledge/p/15947380.html
Copyright © 2020-2023  润新知