• Netflix Ribbon(负载均衡)介绍


    一、Ribbon是什么?

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

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

    二、负载均衡

    负载均衡(Load Balance,简称LB),在微服务或分布式集群中经常用到的一种功能,就是将用户的请求以某种规则平摊到多个服务器上,从而达到系统的高可用

    常见的负载均衡有软件例如Nginx、LVS等等,硬件F5等等。

    相应的在中间件,例如Dubbo和Spring Cloud中均给我们提供了负载均衡,Spring Cloud的负载均衡算法可以自定义。

    集中式负载均衡:即在服务的消费方和提供方之间使用独立的负载均衡设施(可以是硬件,如F5。也可以是软件,如Nginx),由该设施负责把请求通过某种策略转发至服务的提供方。

    进程内负载均衡:将负载均衡逻辑集成到服务消费方,由消费方从服务注册中心获取有那些服务地址可用,然后消费方从这些地址中选择一个合适的服务器。(Ribbon属于进程内负载均衡,它只是一个类库,集成于服务消费方进程,消费方通过它来获取到服务提供方的地址)。

    三、Ribbon的使用

    1. 服务提供者

    (1) 对外提供的方法

    @Controller
    @PropertySource(value = {"classpath:application.properties"})
    public class TestApplicationServiceController {
    
        @Autowired
        private Environment environment;
    
        @RequestMapping("/test")
        @ResponseBody
        public List<Map<String, Object>> test(){
            List<Map<String, Object>> result = new ArrayList<>();
            for(int i = 0; i < 3; i++){
                Map<String, Object> data = new HashMap<>();
                data.put("id", i+1);
                data.put("name", "test name " + i);
                data.put("age", 20+i);
                data.put("server.port",environment.getProperty("server.port") );
                result.add(data);
            }
            return result;
        }
    }

    (2) 启动类

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

    (3) 三个服务提供者

    8862/8872/8888服务提供者的spring.application.name应用名必须是相同的(即对外暴露的统一的服务实例名)。它们区别于端口不同、实例名称不同。

    8862端口:

    # 定义SpringBoot应用的名称,建议必须提供。在SpringCloud中,对服务的最大粒度的管理是使用应用命名的
    # 最好是一个应用一个名称,在Consumer角色开发的时候,比较容易查找Provider
    spring.application.name=appService-name
    server.port=8862
    #eureka微服务实例名称修改,不采用默认的, 默认是spring.application.name的大写
    eureka.instance.instance-id=appService-minsoft-8862
    
    # 配置Eureka Server的地址信息,如果是Eureka Server集群,多个节点使用逗号','分割。
    # 注意:多个地址之间不要有多余的空格, 只有一个逗号
    eureka.client.serviceUrl.defaultZone=http://admin:1234@192.168.178.5:8761/eureka/,http://admin:1234@192.168.178.6:8761/eureka/
    
    #启动所有端点, 也可以设置部分启动, 如:env,beans。默认是health, info
    management.endpoints.web.exposure.include=*
    ## 启用shutdown,优雅停服功能,配置actuator的优雅关闭
    ## actuator 组件监听shutdown请求地址的时候,要求请求的method必须是POST
    ## shutdown的请求地址是使用:@PostMapping或@RequestMapping(method=RequestMethod.POST)
    management.endpoint.shutdown.enabled=true
    
    #访问信息可以使用IP地址
    eureka.instance.prefer-ip-address=true
    # 对该微服务进行简单的信息介绍, 随便配置
    info.app.name=appService-name
    info.app.port=${server.port}
    info.company.name=myApplication
    info.build.artifactId=$project.artifactId$
    info.build.version=$project.version$
    View Code

    8872端口:

    # 定义SpringBoot应用的名称,建议必须提供。在SpringCloud中,对服务的最大粒度的管理是使用应用命名的
    # 最好是一个应用一个名称,在Consumer角色开发的时候,比较容易查找Provider
    spring.application.name=appService-name
    server.port=8872
    #eureka微服务实例名称修改,不采用默认的, 默认是spring.application.name的大写
    eureka.instance.instance-id=appService-minsoft-8872
    
    # 配置Eureka Server的地址信息,如果是Eureka Server集群,多个节点使用逗号','分割。
    # 注意:多个地址之间不要有多余的空格, 只有一个逗号
    eureka.client.serviceUrl.defaultZone=http://admin:1234@192.168.178.5:8761/eureka/,http://admin:1234@192.168.178.6:8761/eureka/
    
    #启动所有端点, 也可以设置部分启动, 如:env,beans。默认是health, info
    management.endpoints.web.exposure.include=*
    ## 启用shutdown,优雅停服功能,配置actuator的优雅关闭
    ## actuator 组件监听shutdown请求地址的时候,要求请求的method必须是POST
    ## shutdown的请求地址是使用:@PostMapping或@RequestMapping(method=RequestMethod.POST)
    management.endpoint.shutdown.enabled=true
    
    #访问信息可以使用IP地址
    eureka.instance.prefer-ip-address=true
    # 对该微服务进行简单的信息介绍, 随便配置
    info.app.name=appService-name
    info.app.port=${server.port}
    info.company.name=myApplication
    info.build.artifactId=$project.artifactId$
    info.build.version=$project.version$
    View Code

    8888端口:

    # 定义SpringBoot应用的名称,建议必须提供。在SpringCloud中,对服务的最大粒度的管理是使用应用命名的
    # 最好是一个应用一个名称,在Consumer角色开发的时候,比较容易查找Provider
    spring.application.name=appService-name
    server.port=8888
    #eureka微服务实例名称修改,不采用默认的, 默认是spring.application.name的大写
    eureka.instance.instance-id=appService-minsoft-8888
    
    # 配置Eureka Server的地址信息,如果是Eureka Server集群,多个节点使用逗号','分割。
    # 注意:多个地址之间不要有多余的空格, 只有一个逗号
    eureka.client.serviceUrl.defaultZone=http://admin:1234@192.168.178.5:8761/eureka/,http://admin:1234@192.168.178.6:8761/eureka/
    
    #启动所有端点, 也可以设置部分启动, 如:env,beans。默认是health, info
    management.endpoints.web.exposure.include=*
    ## 启用shutdown,优雅停服功能,配置actuator的优雅关闭
    ## actuator 组件监听shutdown请求地址的时候,要求请求的method必须是POST
    ## shutdown的请求地址是使用:@PostMapping或@RequestMapping(method=RequestMethod.POST)
    management.endpoint.shutdown.enabled=true
    
    #访问信息可以使用IP地址
    eureka.instance.prefer-ip-address=true
    # 对该微服务进行简单的信息介绍, 随便配置
    info.app.name=appService-name
    info.app.port=${server.port}
    info.company.name=myApplication
    info.build.artifactId=$project.artifactId$
    info.build.version=$project.version$
    View Code

    2. 服务消费者

    Ribbon一般集成于服务消费方。

    (1) 依赖引入

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

    (2) application.properties

    # 定义SpringBoot应用的名称,建议必须提供。
    spring.application.name=app-client
    server.port=8111
    
    # Eureka Server注册地址, 任何Eureka Client都必须注册。
    # 注意:多个地址之间不要有多余的空格, 只有一个逗号
    eureka.client.serviceUrl.defaultZone=http://admin:1234@192.168.178.5:8761/eureka/,http://admin:1234@192.168.178.6:8761/eureka/
    
    # 设置负载均衡策略 appservice-name为调用的服务的名称
    # 没有配置全部服务的负载均衡策略的方式。因为不是每个服务都可以使用相同负载均衡策略的。
    # 如:搜索服务和注册服务就不能使用相同的负载均衡策略。
    # appservice-name.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
    
    # 配置服务列表,其中appservice-name代表要访问的服务的应用名,如果有多个服务结点组成集群,多个节点的配置信息使用逗号','分隔。
    # 配置服务列表,需要配置要调用的服务的名字和服务所在的位置。
    # 服务的名字,就是Application Service(服务提供者)中配置的spring.application.name。
    # 服务的位置,就是服务的所在ip和端口。
    # 如果服务位置有多个,也就是服务集群,那么使用逗号','分割多个服务列表信息。
    appservice-name.ribbon.listOfServers=192.168.178.5:8888,192.168.178.5:8872,192.168.178.5:8862

    (3) 启动类

    @EnableDiscoveryClient //开启服务发现功能
    @SpringBootApplication
    public class AppClient {
        public static void main(String[] args) {
            SpringApplication.run(AppClient.class, args);
        }
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }

    (4) 调用服务接口

    @RestController
    @RequestMapping("/demo")
    public class TestAppController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @GetMapping("/test")
        public Object test() {
            String url = String.format("http://%s/test", "appService-name"); //appService-name为服务的应用名称,最终的请求路径为:http://APPSERVICE-NAME/test
            List<Map<String, Object>> list = restTemplate.getForObject(url, List.class);
            return list;
        }
    }

    (5) 启动eureka,注册服务

     (6) 访问服务消费者:http://192.168.178.6:8111/demo/test

     可以看到每刷新一次,端口就变化。

     注:默认负载均衡算法为轮询算法。

  • 相关阅读:
    根据W3C总结Ajax基础技术
    MVC中ActionName标记属性的用法
    为什么做网站一般不用服务端控件?
    Jquery两个比较常用的方法each和data
    MVC中的路由
    SQL中获取刚插入记录时对应的自增列的值
    第一个文章,今天比较兴奋啊! 给大家一个关于SQL复合查询的文章(动态生成多个where条件)
    获取 汉字的首字母(例如张三返回zs)核心方法chinesecap()
    ASP.NET中判断密码的安全度(低,中,高)
    C# 关于密码加密 (转载)
  • 原文地址:https://www.cnblogs.com/myitnews/p/12495138.html
Copyright © 2020-2023  润新知