zoukankan      html  css  js  c++  java
  • SpirngCloud之Ribbon的服务调用及负载均衡

    一 概念

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

    简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

    LB,即负载均衡(Load Balance),在微服务或分布式集群中经常用的一种应用。 负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA。 常见的负载均衡有软件Nginx,LVS,硬件 F5等。 相应的在中间件,例如:dubbo和SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义。

    Ribbon概述
    是 Netflixfa 发布的一个负载均衡器,有助于控制 HTTP 和 TCP客户端行为。在 SpringCloud 中,
    Eureka一般配合Ribbon进行使用,Ribbon提供了客户端负载均衡的功能,Ribbon利用从Eureka中读
    取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载。
    在SpringCloud中可以将注册中心和Ribbon配合使用,Ribbon自动的从注册中心中获取服务提供者的
    列表信息,并基于内置的负载均衡算法,请求服务

    Ribbon的主要作用
    (1)服务调用
    基于Ribbon实现服务调用, 是通过拉取到的所有服务列表组成(服务名-请求路径的)映射关系。借助
    RestTemplate 最终进行调用
    (2)负载均衡
    当有多个服务提供者时,Ribbon可以根据负载均衡的算法自动的选择需要调用的服务地址

    二 Ribbon配置初步

    • 启动一中的eureka-server项目和producer-service项目,然后再改producer-service的端口,启动2个客户端

      • 修改producer-service的类

         1 @RestController
         2 @RequestMapping("/api/v1/product")
         3 public class ProductController {
         4  5  6  7     @Value("${server.port}")
         8     private String port;
         9 10     @Autowired
        11     private ProductService productService;
        12 13     /**
        14      * 获取所有商品列表
        15      * @return
        16      */
        17     @RequestMapping("list")
        18     public Object list(){
        19         return productService.listProduct();
        20     }
        21 22 23     /**
        24      * 根据id查找商品详情
        25      * @param id
        26      * @return
        27      */
        28     @RequestMapping("find")
        29     public Object findById(int id){
        30 31         Product product = productService.findById(id);
        32 33         Product result = new Product();
        34         BeanUtils.copyProperties(product,result);
        35         result.setName( result.getName() + " data from port="+port );
        36         return result;
        37     }
    • 创建order-serveice项目

      • pom.xml

        <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </dependency>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
                </dependency>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </dependency><dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-test</artifactId>
                    <scope>test</scope>
                </dependency>
            </dependencies>

        注:在springcloud的新版本中提供的服务发现的jar中以及包含了Ribbon的依赖。所以这里不需要导入任何额外的坐标(spring-cloud-starter-netflix-ribbon)

      • 启动类

         1 @SpringBootApplication
         2 public class OrderServiceApplication {
         3  4     public static void main(String[] args) {
         5         SpringApplication.run(OrderServiceApplication.class, args);
         6     }
         7  8  9     @Bean
        10     @LoadBalanced
        11     public RestTemplate restTemplate() {
        12         return new RestTemplate();
        13     }
        14 15 16 }
      • Web层

        @RestController
        @RequestMapping("/api/v1/order")
        public class OrderController {
        ​
        ​
            @Autowired(required = false)
            private ProductOrderServiceImpl productOrderService;
        ​
        ​
            @RequestMapping("/save")
            public Object save(@RequestParam("user_id")int userId, @RequestParam("product_id") int productId){
        ​
                return productOrderService.save(userId, productId);
            }
        ​
        ​
        ​
        ​
        }
      • Service层

        @Service
        public class ProductOrderServiceImpl {
        ​
        ​
            @Autowired
            private RestTemplate restTemplate;
        ​
            public ProductOrder save(int userId, int productId) {
                System.out.println("123");
        ​
                Object obj = restTemplate.getForObject("http://product-service/api/v1/product/find?id="+productId, Object.class);
        ​
                System.out.println(obj);
        ​
                ProductOrder productOrder = new ProductOrder();
                productOrder.setCreateTime(new Date());
                productOrder.setUserId(userId);
                productOrder.setTradeNo(UUID.randomUUID().toString());
        ​
                return productOrder;
            }
        }
      • Bo类

        /**
         * 商品订单实体类
         */
        public class ProductOrder implements Serializable {
        ​
        ​
            private int id;
        ​
            /**
             * 商品名称
             */
            private String productName;
        ​
            /**
             * 订单号
             */
            private  String tradeNo;
        ​
            /**
             * 价格,分
             */
            private int price;
        ​
        ​
            private Date createTime;
        ​
        ​
            private int userId;
        ​
            private String userName;
        ​
        ​
            public int getUserId() {
                return userId;
            }
        ​
            public void setUserId(int userId) {
                this.userId = userId;
            }
        ​
            public String getUserName() {
                return userName;
            }
        ​
            public void setUserName(String userName) {
                this.userName = userName;
            }
        ​
            public int getId() {
                return id;
            }
        ​
            public void setId(int id) {
                this.id = id;
            }
        ​
            public String getProductName() {
                return productName;
            }
        ​
            public void setProductName(String productName) {
                this.productName = productName;
            }
        ​
            public String getTradeNo() {
                return tradeNo;
            }
        ​
            public void setTradeNo(String tradeNo) {
                this.tradeNo = tradeNo;
            }
        ​
            public int getPrice() {
                return price;
            }
        ​
            public void setPrice(int price) {
                this.price = price;
            }
        ​
            public Date getCreateTime() {
                return createTime;
            }
        ​
            public void setCreateTime(Date createTime) {
                this.createTime = createTime;
            }
        }
        ​
      • 配置文件

        server:
          port: 8781
        ​
        ​
        #指定注册中心地址
        eureka:
          client:
            serviceUrl:
              defaultZone: http://localhost:8761/eureka/
        ​
        #服务的名称
        spring:
          application:
            name: order-service
      • 结果:2个结果在轮询

    {id=1, name=iphonex data from port=8772, price=9999, store=10}
    {id=1, name=iphonex data from port=8771, price=9999, store=10}
    {id=1, name=iphonex data from port=8772, price=9999, store=10}
    {id=1, name=iphonex data from port=8771, price=9999, store=10}
    {id=1, name=iphonex data from port=8772, price=9999, store=10}
    {id=1, name=iphonex data from port=8771, price=9999, store=10}

    如要修改它的负载均衡策略:

    service-product:
    ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
  • 相关阅读:
    微信红包开发
    第一次开博客,留此纪念
    数据结构--树(遍历,红黑,B树)
    c++之vector
    动态规划求解最长公共子序列问题
    c++之map
    k-折交叉验证(k-fold crossValidation)
    prim算法
    快速排序算法
    浙大机试题目
  • 原文地址:https://www.cnblogs.com/dalianpai/p/11687175.html
Copyright © 2011-2022 走看看