精华内容
下载资源
问答
  • Ribbon是一款客户端负载均衡工具,可用于微服务中负载均衡,与服务发现配合使用。 使用Ribbon实现服务调用 maven依赖 Ribbon依赖 <dependency> <groupId>org.springframework.cloud</groupId> ...

    客户端负载均衡工具-Ribbon的简单使用

    简介

    Ribbon是一款客户端负载均衡工具,可用于微服务中负载均衡,与服务发现配合使用。

    使用Ribbon实现服务调用

    maven依赖

    • Ribbon依赖
    <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-eureka-client</artifactId>
    </dependency>
    

    服务发现与负载均衡

    开启服务发现功能:

    @SpringBootApplication
    @EnableDiscoveryClient
    public class InterventionServiceApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(InterventionServiceApplication.class, args);
        }
    
    }
    
    1. 通过DiscoveryClient进行服务发现

    DiscoveryClient是SpringCloud对于服务发现机制的抽象,这种方式不通过Ribbon进行负载均衡。通过以下方式实现服务发现与负载均衡:

    • 首先注册一个RestTemplate
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    • 使用DiscoveryClient进行服务发现,使用RestTemplate进行服务调用
    	@Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private DiscoveryClient discoveryClient;
    
        @GetMapping("/user")
        public User getUserByUserName() {
            // 负载均衡方式一:通过DiscoveryClient获取实例列表
            List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
            if (instances.size() == 0) {
                return null;
            }
    
            // 自定义负载均衡策略
            // 这里mockUser是远程服务user-service的参数
            // 远程服务完整路径:http://user-service/users/{username}
            String url = String.format("%s/users/%s", instances.get(0).getUri().toString(), "mockUser");
    
            // 通过一般的RestTemplate进行请求
            ResponseEntity<User> result = restTemplate.exchange(url, HttpMethod.GET, null, User.class);
    
            return result.getBody();
        }
    
    • 这种方式可自定义负载均衡策略,推荐使用下面的方式,即Ribbon调用的方式
    1. 使用Ribbon进行服务发现与负载均衡
    • 首先注册具有负载均衡功能的RestTemplate
    @LoadBalanced
    @Bean
    public RestTemplate loadBalanceRestTemplate() {
        return new RestTemplate();
    }
    
    • 使用这个RestTemplate进行服务调用
    @Qualifier
    @Autowired
    private RestTemplate loadBalanceRestTemplate;
        
    @GetMapping("/user/v2")
    public User getUserByUserNameV2(String username) {
        // 负载均衡方式二:通过加了LoadBalanced注解的RestTemplate获取服务实例,内部已经实现负载均衡,user-service是服务名称
        String url = "http://user-service/users/{username}";
    
        ResponseEntity<User> result = loadBalanceRestTemplate.exchange(url, HttpMethod.GET, null, User.class, username);
    
        return result.getBody();
    }
    

    至此,Ribbon的集成使用已经完成,思考:为什么@LoadBalanced标记的RestTemplate具备负载均衡能力?

    微服务服务调用-RestTemplate通过@LoadBalaced具备负载均衡与服务发现的原理

    展开全文
  • SpringCloud微服务Ribbon负载均衡及Feign应用微服务调用Ribbon简介初步应用Ribbon负载均衡Feign简介及应用简介应用 微服务调用Ribbon 简介 前面讲了eureka服务注册与发现,但是结合eureka集群的服务调用没讲。 这里...

    微服务调用Ribbon

    简介

    前面讲了eureka服务注册与发现,但是结合eureka集群的服务调用没讲。
    这里的话 就要用到Ribbon,结合eureka,来实现服务的调用;

    Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为。为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。
    在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。展示了Ribbon与Eureka配合使用时的架构。

    在这里插入图片描述
    在这里插入图片描述

    初步应用

    Ribbon是客户端负载均衡,所以肯定集成再消费端,也就是consumer端
    我们修改microservice-student-consumer-80
    首先,引入依赖,pom.xml 加入 ribbon相关依赖

     <!--ribbon相关依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-ribbon</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-config</artifactId>
            </dependency>
    

    application.yml加

    server:
      port: 80
      context-path: /
    eureka:
      client:
        service-url:
          defaultZone: http://eureka2001.liuchunming.com:2001/eureka/,http://eureka2002.liuchunming.com:2002/eureka/,http://eureka2003.liuchunming.com:2003/eureka/
        register-with-eureka: false
    

    ribbon结合eureka来调用服务提供者;

    SpringCloudConfig也改成 要加个负载均衡配置 @LoadBalanced

    package com.liuchunming.microservicestudentconsumer80.config;
    
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class SpringCloudConfig {
    
        @LoadBalanced  // 引入ribbon负载均衡
        @Bean
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    }
    
    

    因为和eureka整合,所以启动类StudentConsumerApplication_80 加个注解 @EnableEurekaClient

    package com.liuchunming.microservicestudentconsumer80;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @EnableEurekaClient
    @SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
    public class MicroserviceStudentConsumer80Application {
    
        public static void main(String[] args) {
            SpringApplication.run(MicroserviceStudentConsumer80Application.class, args);
        }
    
    }
    
    

    这里还有一个,要修改下StudentConsumerController的PRE_HOST,改成指定的微服务应用名称;
    当然这里要先在服务提供者microservice-student-provider-1001的application.yml加下配置,指定下应用名称:

    application:
        name: microservice-student
    

    在这里插入图片描述
    我们的微服务应用名称是 microservice-student
    所以服务调用者这边的控制器里PRE_HOST改成 http://MICROSERVICE-STUDENT即可;
    MICROSERVICE-STUDENT为Eureka注册中心的应用名称
    在这里插入图片描述
    上面配置好后,我们可以测试下;
    先启动三个eureka,然后再启动服务提供者,再启动服务消费者;

    在这里插入图片描述
    在这里插入图片描述

    结果就出来了,说明配置OK;

    Ribbon负载均衡

    按照它microservice-student-provider-1001建立一个microservice-student-provider项目。前面搭建了初步例子,但是还没实现真正负载均衡,我们这里要先搞三个服务提供者集群,然后才能演示负载均衡,以及负载均衡策略;
    创建microservice-student-provider项目
    在这里插入图片描述
    相关代码如下
    相关pom

    <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>com.liuchunming</groupId>
            <artifactId>t243microservice</artifactId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <artifactId>microservice-student-provider</artifactId>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
            </dependency>
            <!--  修改后立即生效,热部署  -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>springloaded</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
            <dependency>
                <groupId>com.liuchunming</groupId>
                <artifactId>microservice-common</artifactId>
                <version>1.0-SNAPSHOT</version>
                <scope>compile</scope>
            </dependency>
            <!--添加注册中心Eureka相关配置-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-config</artifactId>
            </dependency>
            <!-- actuator监控引入 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    
    </project>
    
    

    Yml文件

    ---
    server:
      port: 1001
      context-path: /
    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/liuchunming?useUnicode=true&characterEncoding=utf8
        username: root
        password: 123
      jpa:
        hibernate:
          ddl-auto: update
        show-sql: true
      application:
        name: microservice-student
      profiles: provider-1001
    
    eureka:
      instance:
        hostname: localhost
        appname: microservice-student
        instance-id: microservice-student:1001
        prefer-ip-address: true
      client:
        service-url:
          defaultZone: http://eureka2001.liuchunming.com:2001/eureka/,http://eureka2002.liuchunming.com:2002/eureka/,http://eureka2003.liuchunming.com:2003/eureka/
    
    info:
      groupId: com.liuchunming.testSpringcloud
      artifactId: microservice-student-provider-1001
      version: 1.0-SNAPSHOT
      userName: http://liuchunming.com
      phone: 123456
    
    ---
    server:
      port: 1002
      context-path: /
    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/liuchunming?useUnicode=true&characterEncoding=utf8
        username: root
        password: 123
      jpa:
        hibernate:
          ddl-auto: update
        show-sql: true
      application:
        name: microservice-student
      profiles: provider-1002
    
    eureka:
      instance:
        hostname: localhost
        appname: microservice-student
        instance-id: microservice-student:1002
        prefer-ip-address: true
      client:
        service-url:
          defaultZone: http://eureka2001.liuchunming.com:2001/eureka/,http://eureka2002.liuchunming.com:2002/eureka/,http://eureka2003.liuchunming.com:2003/eureka/
    
    info:
      groupId: com.liuchunming.testSpringcloud
      artifactId: microservice-student-provider-1002
      version: 1.0-SNAPSHOT
      userName: http://liuchunming.com
      phone: 123456
    
    ---
    server:
      port: 1003
      context-path: /
    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/liuchunming?useUnicode=true&characterEncoding=utf8
        username: root
        password: 123
      jpa:
        hibernate:
          ddl-auto: update
        show-sql: true
      application:
        name: microservice-student
      profiles: provider-1003
    
    eureka:
      instance:
        hostname: localhost
        appname: microservice-student
        instance-id: microservice-student:1003
        prefer-ip-address: true
      client:
        service-url:
          defaultZone: http://eureka2001.liuchunming.com:2001/eureka/,http://eureka2002.liuchunming.com:2002/eureka/,http://eureka2003.liuchunming.com:2003/eureka/
    
    info:
      groupId: com.liuchunming.testSpringcloud
      artifactId: microservice-student-provider-1003
      version: 1.0-SNAPSHOT
      userName: http://liuchunming.com
      phone: 123456
    
    

    启动类

    package com.liuchunming.microservicestudentprovider;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.domain.EntityScan;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @EntityScan("com.liuchunming.*.*")
    @EnableEurekaClient
    @SpringBootApplication
    public class MicroserviceStudentProviderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MicroserviceStudentProviderApplication.class, args);
        }
    
    }
    
    

    StudentProviderController.java

        @Value("${server.port}")
        private String port;
    
        @RequestMapping("/ribbon")
        public String ribbon(){
            return "工号【"+port+"】正在为您服务";
        }
    
    

    在student-consumer-80的StudentConsumerController.java添加

        @RequestMapping("/ribbon")
        public String ribbon() {
            return restTemplate.getForObject(SERVER_IP_PORT + "/student/ribbon", String.class);
        }
    

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    但是这种默认的轮询策略肯定是不能满足实际需求的,比如有3个服务提供者,突然挂了一个,这样的话,默认轮询 ,总有1/3的概率访问失败; 所以我们看下ribbon默认给我们提供的策略有哪些;

    策略名策略声明
    BestAvailableRulepublic class BestAvailableRule extends ClientConfigEnabledRoundRobinRule
    AvailabilityFilteringRulepublic class AvailabilityFilteringRule extends PredicateBasedRule
    WeightedResponseTimeRulepublic class WeightedResponseTimeRule extends RoundRobinRule
    RetryRulepublic class RetryRule extends AbstractLoadBalancerRule
    RoundRobinRulepublic class RoundRobinRule extends AbstractLoadBalancerRule
    RandomRulepublic class RandomRule extends AbstractLoadBalancerRule
    ZoneAvoidanceRulepublic class ZoneAvoidanceRule extends PredicateBasedRule

    默认7个策略,根据具体产品需求,我们选用;

    服务消费端 SpringCloudConfig配置类

    /**
         * 自定义轮询算法
         * @return
         */
        @Bean
        public IRule myRule(){
            return new RetryRule();
        }
    

    Feign简介及应用

    简介

    声明式服务调用Feign简单介绍下;

    Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解。Feign也支持可插拔的编码器和解码器。Spring Cloud为Feign增加了对Spring MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。

    这段话看起来比较懵逼,这里说下实际使用,前面Ribbon调用服务提供者,我们通过restTemplate调用,缺点是,多个地方调用,同一个请求要写多次,不方便统一维护,这时候Feign来了,就直接把请求统一搞一个service作为FeignClient,然后其他调用Controller需要用到的,直接注入service,直接调用service方法即可;同时Feign整合了Ribbon和Eureka,所以要配置负载均衡的话,直接配置Ribbon即可,无其他特殊地方;当然Fiegn也整合了服务容错保护,断路器Hystrix,后面再说。

    应用

    1、在common项目里建一个service(实际项目肯定是多个service)作为Feign客户端,用Feign客户端来调用服务器提供者,当然可以配置负载均衡;Feign客户端定义的目的,就是为了方便给其他项目调用;
    修改 microservice-common

     <!--引入Feign依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
            </dependency>
    

    建StudentClientService接口;

    package com.liuchunming.microservicecommon.service;
    
    import com.liuchunming.microservicecommon.entity.Student;
    import org.springframework.cloud.netflix.feign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import java.util.List;
    
    /**
     * Student Feign接口客户端
     * @author Administrator
     *
     */
    @FeignClient(value="MICROSERVICE-STUDENT")
    public interface StudentClientService {
     
        /**
         * 根据id查询学生信息
         * @param id
         * @return
         */
        @GetMapping(value="/student/get/{id}")
        public Student get(@PathVariable("id") Integer id);
         
        /**
         * 查询学生信息
         * @return
         */
        @GetMapping(value="/student/list")
        public List<Student> list();
         
        /**
         * 添加或者修改学生信息
         * @param student
         * @return
         */
        @PostMapping(value="/student/save")
        public boolean save(Student student);
         
        /**
         * 根据id删除学生信息
         * @return
         */
        @GetMapping(value="/student/delete/{id}")
        public boolean delete(@PathVariable("id") Integer id);
    
        @RequestMapping("/student/ribbon")
        public String ribbon();
    }
    
    

    2、新建一个Feign消费者项目;
    参考microservice-student-consumer-80建一个microservice-student-consumer-feign-80
    代码都复制一份,包括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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>com.liuchunming</groupId>
            <artifactId>t243microservice</artifactId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <artifactId>microservice-student-consumer-feign-80</artifactId>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </dependency>
            <!--  修改后立即生效,热部署  -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>springloaded</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
            <dependency>
                <groupId>com.liuchunming</groupId>
                <artifactId>microservice-common</artifactId>
                <version>1.0-SNAPSHOT</version>
                <scope>compile</scope>
            </dependency>
            <!--ribbon相关依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-ribbon</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-config</artifactId>
            </dependency>
            <!--引入Feign依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    

    SpringCloudConfig.java

    package com.liuchunming.microservicestudentconsumerfeign80.config;
    
    import com.netflix.loadbalancer.IRule;
    import com.netflix.loadbalancer.RetryRule;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class SpringCloudConfig {
    
        @LoadBalanced  // 引入ribbon负载均衡
        @Bean
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    
        /**
         * 自定义调用规则(服务提供者掉线后不再调用,解决轮询问题)
         * @return
         */
        @Bean
        public IRule myRule(){
            return new RetryRule();
    //        return new RandomRule();
        }
    }
    
    

    Yml文件

    server:
      port: 80
      context-path: /
    eureka:
      client:
        service-url:
          defaultZone: http://eureka2001.liuchunming.com:2001/eureka/,http://eureka2002.liuchunming.com:2002/eureka/,http://eureka2003.liuchunming.com:2003/eureka/
        register-with-eureka: false
    
    
    

    3、修改启动类名称,和加注解
    启动类名称改下,改成StudentConsumerFeignApplication_80,同时加个注解@EnableFeignClients
    支持下Feign;

    package com.liuchunming.microservicestudentconsumerfeign80;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.netflix.feign.EnableFeignClients;
    
    @EnableEurekaClient
    @EnableFeignClients(value = "com.liuchunming.*.*")
    @SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
    public class MicroserviceStudentConsumerFeign80Application {
    
        public static void main(String[] args) {
            SpringApplication.run(MicroserviceStudentConsumerFeign80Application.class, args);
        }
    
    }
    
    

    StudentConsumerController.java

    package com.liuchunming.microservicestudentconsumerfeign80.controller;
    
    import com.liuchunming.microservicecommon.entity.Student;
    import com.liuchunming.microservicecommon.service.StudentClientService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.List;
    
    @RestController
    @RequestMapping("/student")
    public class StudentConsumerController {
    
        @Autowired
        private StudentClientService studentClientService;
    
        @Autowired
        private RestTemplate restTemplate;
    
        @PostMapping(value = "/save")
        private boolean save(Student student) {
            return studentClientService.save(student);
        }
    
        @GetMapping(value = "/list")
        public List<Student> list() {
            return studentClientService.list();
        }
    
        @GetMapping(value = "/get/{id}")
        public Student get(@PathVariable("id") Integer id) {
            return studentClientService.get(id);
        }
    
        @GetMapping(value = "/delete/{id}")
        public boolean delete(@PathVariable("id") Integer id) {
            try {
                studentClientService.delete(id);
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    
        @RequestMapping("/ribbon")
        public String ribbon(){
            return studentClientService.ribbon();
        }
    }
    
    

    因为现在用Fiegn,所以把restTemplate去掉,改成注入service,调用service方法来实现服务的调用;
    5、测试负载均衡;
    在这里插入图片描述

    展开全文
  • 微服务调用Ribbon

    2020-03-28 15:45:35
    Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为,为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多负载均衡算法,...

    Ribbon简介

    Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为,为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等,当然,我们也可为Ribbon实现自定义的负载均衡算法

    在SpringCloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从EurekaServer获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。下图展示了Ribbon与Eureka配合使用时的架构:

    Ribbon的初步应用

    Ribbon是客户端负载均衡,所以是集成在消费端,也就是consumer端,本例在前面的基础上修改microservice-student-consumer-80模块

    首先,引入依赖,在pom.xml加入ribbon相关依赖:

    <!--ribbon相关依赖-->
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-ribbon</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

    然后在application.yml加入(为了使ribbon结合eureka来调用服务提供者):

    eureka:
      client:
        register-with-eureka: false
        service-url:
          defaultZone: http://eureka2001.test.com:2001/eureka/,http://eureka2002.test.com:2002/eureka/,http://eureka2003.test.com:2003/eureka/

    然后在SpringCloudConfig.java里加个负载均衡配置@LoadBalanced:

    因为是和Eureka整合,而服务端跟消费端相对于注册中心来说都是client,所以要在启动类StudentConsumerApplication_80.java加个@EnableEurekaClient注解:

    然后修改下StudentConsumerController.java里的PRE_HOST变量,改成指定的微服务应用名称;当然要先在服务提供者microservice-student-provider-1001的application.yml加下配置,指定下应用名称:

    微服务的应用名称是microservice-student,所以把服务调用者这边的控制器里的PRE_HOST变量改成http://MICROSERVICE-STUDENT即可(MICROSERVICE-STUDENT为Eureka注册中心的应用名称,需大写):

    上面的都配置好后,就可以开始测试了;先启动两个Eureka,然后再启动服务提供者,再启动服务消费者:

    在浏览器的地址栏输入http://localhost/student/list,出现如下结果,说明配置OK:

    展开全文
  • 微服务相互调用-Ribbon 稍微LOW,也是不常用的技术 RestTemplate->Ribbon 前面,已经通过RestTemplate可以实现微服务之间的相互调用,但是RestTemplate有一定的问题,问题:1、必须要确定的具体地址。2、如果具体...

    微服务相互调用-Ribbon

    稍微LOW,也是不常用的技术

    RestTemplate->Ribbon

    前面,已经通过RestTemplate可以实现微服务之间的相互调用,但是RestTemplate有一定的问题,问题:1、必须要确定的具体地址。2、如果具体地址出问题了,就无法正常的做自动切换。3、微服务都是以集群的方式来部署,无法去选择集群中其他地址

    解决方案

    Ribbon

    Ribbon概述

    Ribbon是NetFlex的一个负载均衡器,例外它还可以同样使用RestTemplate完成对微服务之间的调用

    你可以认为:Ribbon就是在RestTemplate的基础之上,提供了负载均衡的能力

    Ribbon一般是配合Eureka注册中心来使用,意味着:Ribbon可以从Eureka中去发现自己需要的微服务实例

    负载均衡

    Ribbon提供的这种负载均衡的原理,是一种客户端的负载均衡机制

    负载均衡:将负载(HTTP的请求)较为平均的分配到服务器上去

    负载均衡常见的算法:轮询,权重,IP地址黏贴,最少连接

    负载均衡的分类

    **服务端负载均衡:**服务端的这种方式,一定是有服务器(Apache/Nginx)在参与,它的原理:包工头-工人之间的关系,它是属于任务分配的一种方式

    **客户端负载均衡:**客户端的负载均衡一般是发生在分布式应用程序内容,它的原理:是属于调用者与被调用者之间的关系

    Ribbon使用

    1、导入Ribbon的依赖

    但是Ribbon只要是你使用Eureka,那么程序已经自带了

    2、开启负载均衡

    在调用的一方,开启负载均衡

    配置Ribbon实际上就是开启它的负载均衡

    说Ribbon的底层就是RestTemplate,那么配置Ribbon实际上就是在配置RestTemplate

        /**
         * 产生一个RestTemplate 模板对象
         * @return
         */
        @LoadBalanced
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    
    
    

    **默认情况下:**Ribbon使用的轮询模式

    3、客户端调用方式
        /**
         * RestTemplate一定要写详细地址
         * @return
         */
        public String getUrl(){
    //        return "http://127.0.0.1:9091/";
            //127.0.0.1:9091替换成 micro-base-server(被调用者的spring.application.name)
            return "http://micro-base-server/";
        }
    
    4、Ribbon提供的负载均衡

    com.netflix.loadbalancer.RoundRobinRule 轮询(默认)

    com.netflix.loadbalancer.RandomRule 随机

    com.netflix.loadbalancer.RetryRul 重试

    com.netflix.loadbalancer.WeightedResponseTimeRule 权重

    com.netflix.loadbalancer.BestAvailableRule 最佳

    com.netflix.loadbalancer.AvailabilityFilteringRule 请求过滤

    5、全局配置Ribbon的负载均衡

    在SpringMvcConfiguration中

        /**
         * 定义自己的负载均衡策略
         * @return
         */
        @Bean
        public IRule myRandomRule(){
            return new RandomRule();
        }
    
    6、局部配置Ribbon的负载均衡

    每个单独的微服务调用,可能使用的负载均衡策略不一致,那么如何设置呢?

    以RetryRule的方式来讲解,注释掉 上述的全局负载均衡的代码

    image-20201231101002327

    Ribbon在使用restTemplate调用其他的微服务时,调用可能由于某些原因失败了,失败了肯定要解决,采用重试机制解决

    1、导入重试依赖包

    在调用者一方的pom.xml中

    <dependency>
                <groupId>org.springframework.retry</groupId>
                <artifactId>spring-retry</artifactId>
      </dependency>
    
    2、修改application.yml文件
    spring:
      application:
        name: micro-user-server
      datasource: #配置Druid的数据源连接池
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/micro-user-server?useUnicode=true&characterEncoding=UTF8&allowMultiQueries=true
        username: root
        password: 123456
        druid:
          initial-size: 5
          max-active: 20
          min-idle: 1
          time-between-eviction-runs-millis: 60000
          min-evictable-idle-time-millis: 300000
          validation-query: select now() from dual
          test-while-idle: false
          test-on-borrow: true
          test-on-return: false
          pool-prepared-statements: true
          max-pool-prepared-statement-per-connection-size: 20
          filters: stat,wall
          connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=3000
          stat-view-servlet:
            enabled: true
            login-username: druid
            login-password: druid
            reset-enable: true
            url-pattern: /druid/*
          web-stat-filter:
            enabled: true
            exclusions:
              -*.js
              -*.gif
              -*.jpg
              -*.png
              -*.css
              -*.ico
              -/druid/*
            url-pattern: /*
            
    micro-base-server: #微服务的名称
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule
        ConnectTimeout: 250 # Ribbon的连接超时时间(毫秒)
        ReadTimeout: 1000 # Ribbon的数据读取超时时间
        OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
        MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
        MaxAutoRetries: 1 # 对当前实例的重试次数
    
    #设置其他微服务的负载均衡策略
    #micro-admin-server:
    #  ribbon:
    #    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    #
    
    server:
      port: 9092
    eureka:
      client:
        service-url:
          defaultZone: http://127.0.0.1:8080/eureka/
    mybatis:
      mapper-locations: classpath:mapper/*.xml #配置Mapper映射文件所在的位置
      type-aliases-package: com.woniuxy.microuserserver.bean #别名包
      configuration:
        lazy-loading-enabled: true #延迟加载
        aggressive-lazy-loading: false
    logging:
      level:
        root: debug #将日志下调至Debug
    

    logging.level.root 为了查看效果, 可以将日志级别下调至Debug

    micro-base-server 单独为该微服务,定制化的设置 负载均衡规则

    3、查看重试效果

    image-20201231103546900

    g:
    level:
    root: debug #将日志下调至Debug

    
    > logging.level.root 为了查看效果, 可以将日志级别下调至Debug
    >
    > micro-base-server 单独为该微服务,定制化的设置 负载均衡规则
    
    ##### 3、查看重试效果
    
    [外链图片转存中...(img-METyJF0i-1615996793648)]
    
    
    
    
    
    
    
    
    展开全文
  • 微服务调用Ribbon 简介 前面讲了eureka服务注册与发现,但是结合eureka集群的服务调用没讲。 这里的话 就要用到Ribbon,结合eureka,来实现服务调用Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的...
  • 微服务调用Ribbon 简介 前面讲了eureka服务注册与发现,但是结合eureka集群的服务调用没讲。 这里的话 就要用到Ribbon,结合eureka,来实现服务调用Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的...
  • 参考以下网址 https://blog.csdn.net/wufewu/article/details/84679962
  • ribbon 可以看到Feign 调用步骤...只需要在implements 接口类里面引入一个ribbon 均衡,再方法中调用即可 /** * www.1b23.com */ @Service @Transactional //开启事物 public class UsersServiceImpl implem...
  • 可以直接正常访问微服务,但是通过Ribbon或者Feign调用...通过Ribbon调用服务时异常如下: 通过Feign调用服务时异常如下: 可能是打开了idea中HTTP代理造成的,只需要关闭HTTP代理即可正常访问,如下图: ...
  • OpenFeign不会出现这个错误,因为和ribbon请求其他服务的方式不同。 下面这个是基于ribbon的。 服务提供者 在这里写这个用了@RequestBody注解。这样是不对的。 我感觉我上面写的那传递参数是值传递,也就是字符串...
  • springcloud微服务工程源码,包括eureka注册中心,reign,ribbon微服务调用源码,实现查看详情,列表查询功能
  • 微服务服务调用微服务架构中,要调用很多服务才能完成一项功能。服务之间如何互相调用就变成微服务架构中的一个关键问题。服务调用有两种方式,一种是RPC方式,另一种是事件驱动(Event-driven)方式,也就是发...
  • 项目地址:https://gitee.com/shao_yi_feng/kubernetes-client.git
  • Ribbon 负载均衡服务调用8.1 概述1. Ribbon 是什么2. 官网资料3. 能干什么3.1 LB(负载均衡)8.2 Ribbon负载均衡演示1.架构说明2. pom3. RestTemplate 的使用8.3 Ribbon核心组件IRule如何替换?8.4 Ribbon负载均衡...
  • 文章目录微服务服务调用一,事件驱动(Event-Driven)方式事件通知(Event Notification)方式事件溯源(Event Sourcing)方式二,RPC方式:三,总结Spring Cloud Feign概述与工作原理解读一,服务调用的几种方式二,...
  • Springcloud微服务操作 微服务的概念? 将all in one 和 soa 框架的缺点都弥补了的框架结构 微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是...
  • I/O erroronGET requestfor... nested exceptionisjava.net.UnknownHostException:280d0f4200d8 280d0f4200d8 : Docker镜像ID ribbon 无法映射到SERVICE的宿主机IP. ...
  • RestTemplate通过@LoadBalaced注解集成Ribbon 疑问: 为什么RestTemplate上加一个@LoadBalaced注解即具备服务发现与负载均衡的能力? 为什么通过@Qualifier就能注入具有负载均衡能力的RestTemplate?
  • Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,867
精华内容 9,946
关键字:

微服务ribbon怎么调用服务