SpringCloud(4)---Ribbon服务调用,源码分析
2021-07-09 02:17
                         标签:web   beanutils   oid   img   苹果   eureka   post   htm   获得    本篇模拟订单服务调用商品服务,同时商品服务采用集群部署。 注册中心服务端口号7001,订单服务端口号9001,商品集群端口号:8001、8002、8003。 各服务的配置文件这里我这边不在显示了,和上篇博客配置一样。博客地址:SpringCloud(3)---Eureka服务注册与发现     多调几次接口,看后台打印 发现订单服务去掉商品服务的时候,不是固定节点,而且集群的每个节点都有可能。所以通过Ribbon实现了负载均衡。   在springcloud中,引入Ribbon来作为客户端时,负载均衡使用的是被       RestTemplate 是Spring自己封装的http请求的客户端,也就是说它只能发送一个正常的Http请求,这跟我们要求的负载均衡是有出入的,还有就是这个请求的链接上的域名 是我们微服的一个服务名,而不是一个真正的域名,那它是怎么实现负载均衡功能的呢? 我们来看看RestTemplate的父类InterceptingHttpAccessor。       从源码我们可以知道InterceptingHttpAccessor中有一个拦截器列表List 拦截器,所以只要给RestTemplate添加拦截器,而这个拦截器中的逻辑就是Ribbon的负载均衡的逻辑。通过 具体的拦截器的生成在LoadBalancerAutoConfiguration这个配置类中,所有的RestTemplate的请求都会转到Ribbon的负载均衡器上 (当然这个时候如果你用RestTemplate发起一个正常的Http请求时走不通,因为它找不到对应的服务。)这样就实现了Ribbon的请求的触发。 上面提到过,发起http后请求后,请求会到达到达拦截器中,在拦截其中实现负载均衡,先看看代码:       我们可以看到在intercept()方法中实现拦截的具体逻辑,首先会根据传进来的请求链接,获取微服的名字serviceName,然后调用LoadBalancerClient的 execute(String serviceId, LoadBalancerRequest 而这个实现类就是RibbonLoadBalancerClient,看看execute()的源码:        首先是获得均衡器ILoadBalancer这个类上面讲到过这是Netflix Ribbon中的均衡器,这是一个抽象类,具体的实现类是ZoneAwareLoadBalancer上面也讲到过, 每一个微服名对应一个均衡器,均衡器中维护者微服名下所有的服务清单。getLoadBalancer()方法通过serviceId获得对应的均衡器,getServer()方法通过对应的均衡器 在对应的路由的算法下计算得到需要路由到Server,Server中有该服务的具体域名等相关信息。得到了具体的Server后执行正常的Http请求,整个请求的负载均衡逻辑就完成了。 在微服中Ribbon和 Hystrix通常是一起使用的,其实直接使用Ribbon和Hystrix实现服务间的调用并不是很方便,通常在Spring Cloud中我们使用Feign完成服务间的调用, 而Feign是对Ribbon和Hystrix做了进一步的封装方便大家使用,对Ribbon的学习能帮你更好的完成Spring Cloud中服务间的调用。    我只是偶尔安静下来,对过去的种种思忖一番。那些曾经的旧时光里即便有过天真愚钝,也不值得谴责。毕竟,往后的日子,还很长。不断鼓励自己,  天一亮,又是崭新的起点,又是未知的征程(上校6)     SpringCloud(4)---Ribbon服务调用,源码分析 标签:web   beanutils   oid   img   苹果   eureka   post   htm   获得    原文地址:https://www.cnblogs.com/qdhxhz/p/9568481.html SpringCloud(4)---Ribbon

一、商品中心服务端
   1、pom.xml


xml version="1.0" encoding="UTF-8"?>
project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    modelVersion>4.0.0modelVersion>
    groupId>com.jincougroupId>
    artifactId>productartifactId>
    version>0.0.1-SNAPSHOTversion>
    packaging>jarpackaging>
    name>productname>
    description>Demo project for Spring Bootdescription>
    parent>
        groupId>org.springframework.bootgroupId>
        artifactId>spring-boot-starter-parentartifactId>
        version>2.0.4.RELEASEversion>
        relativePath/> 
    parent>
    properties>
        project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        java.version>1.8java.version>
        
        spring-cloud.version>Finchley.RELEASEspring-cloud.version>
    properties>
    dependencies>
        dependency>
            groupId>org.springframework.bootgroupId>
            artifactId>spring-boot-starter-webartifactId>
        dependency>
        dependency>
            groupId>org.springframework.bootgroupId>
            artifactId>spring-boot-starter-testartifactId>
            scope>testscope>
        dependency>
        
        dependency>
            groupId>org.springframework.cloudgroupId>
            artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
        dependency>
            groupId>org.projectlombokgroupId>
            artifactId>lombokartifactId>
            scope>providedscope>
        dependency>
    dependencies>
    dependencyManagement>
        dependencies>
            dependency>
                groupId>org.springframework.cloudgroupId>
                artifactId>spring-cloud-dependenciesartifactId>
                version>${spring-cloud.version}version>
                type>pomtype>
                scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>
    build>
        plugins>
            plugin>
                groupId>org.springframework.bootgroupId>
                artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>
project>
  2、Product商品实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product implements Serializable {
    private int id;
    //商品名称
    private String name;
    //价格,分为单位
    private int price;
    //库存
    private int store;
}
   3、ProductService商品接口
public interface ProductService {
    //查找所有商品
    List
   4、ProductServiceImpl商品实现类
@Service
public class ProductServiceImpl implements ProductService {
    private static final Map
     5、ProductController
@RestController
@RequestMapping("/api/v1/product")
public class ProductController {
    //集群情况下,用于订单服务查看到底调用的是哪个商品微服务节点
    @Value("${server.port}")
    private String port;
    @Autowired
    private ProductService productService;
     //获取所有商品列表
    @RequestMapping("list")
    public Object list(){
        return productService.listProduct();
    }
    //根据id查找商品详情
    @RequestMapping("find")
    public Object findById(int id){
        Product product = productService.findById(id);
        Product result = new Product();
        BeanUtils.copyProperties(product,result);
        result.setName( result.getName() + " data from port="+port );
        return result;
    }
}
      6、测下该服务接口是否成功

二、订单中心服务端
    1、pom.xml


xml version="1.0" encoding="UTF-8"?>
project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    modelVersion>4.0.0modelVersion>
    groupId>com.jincougroupId>
    artifactId>orderartifactId>
    version>0.0.1-SNAPSHOTversion>
    packaging>jarpackaging>
    name>ordername>
    description>Demo project for Spring Bootdescription>
    parent>
        groupId>org.springframework.bootgroupId>
        artifactId>spring-boot-starter-parentartifactId>
        version>2.0.4.RELEASEversion>
        relativePath/> 
    parent>
    properties>
        project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        java.version>1.8java.version>
        spring-cloud.version>Finchley.RELEASEspring-cloud.version>
    properties>
    dependencies>
        dependency>
            groupId>org.springframework.bootgroupId>
            artifactId>spring-boot-starter-webartifactId>
        dependency>
        dependency>
            groupId>org.springframework.bootgroupId>
            artifactId>spring-boot-starter-testartifactId>
            scope>testscope>
        dependency>
        
        dependency>
            groupId>org.springframework.cloudgroupId>
            artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
        dependency>
            groupId>org.projectlombokgroupId>
            artifactId>lombokartifactId>
            scope>providedscope>
        dependency>
    dependencies>
    dependencyManagement>
        dependencies>
            dependency>
                groupId>org.springframework.cloudgroupId>
                artifactId>spring-cloud-dependenciesartifactId>
                version>${spring-cloud.version}version>
                type>pomtype>
                scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>
    build>
        plugins>
            plugin>
                groupId>org.springframework.bootgroupId>
                artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>
project>
   2、ProductOrder商品订单实体
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProductOrder implements Serializable {  
    //订单ID
    private int id;
    // 商品名称
    private String productName;
    //订单号
    private String tradeNo;
    // 价格,分
    private int price;
    //订单创建时间
    private Date createTime;
    //用户id
    private int userId;
    //用户名
    private String userName;
}
     3、ProductOrderService订单接口
/**
 * 订单业务类
 */
public interface ProductOrderService {
     //下单接口
     ProductOrder save(int userId, int productId);
}
     4、ProductOrderServiceImpl订单实现类
@Service
public class ProductOrderServiceImpl implements ProductOrderService {
    @Autowired
    private RestTemplate restTemplate;
    @Override
    public ProductOrder save(int userId, int productId) {
        //product-service是微服务名称(这里指向的商品微服务名称),api/v1/product/find?id=? 就是商品微服务对外的接口
        Map
     5、OrderController类
@RestController
@RequestMapping("api/v1/order")
public class OrderController {
    
    @Autowired
    private ProductOrderService productOrderService;
    
    @RequestMapping("save")
    public Object save(@RequestParam("user_id")int userId, @RequestParam("product_id") int productId){
    return productOrderService.save(userId, productId);
    }
}
    6、SpringBoot启动类
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
    //当添加@LoadBalanced注解,就代表启动Ribbon,进行负载均衡
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
    7、接口测试


三、Ribbon源码分析
    1、@LoadBalanced注解作用
@LoadBalanced修饰的RestTemplate对象。
@LoadBalanced注解为RestTemplate配置添加拦截器。     2.拦截器都做了什么?


文章标题:SpringCloud(4)---Ribbon服务调用,源码分析
文章链接:http://soscw.com/index.php/essay/102579.html