spring cloud之ribbon负载均衡,eureka分布式服务注册

目录

一、目标

二、组成成员

三、示例


 

一、目标

学会使用spring cloud ribbon进行服务负载调度,所有微服务由eureka发现注册服务。

二、组成成员

整个模块可以分化为3个部分:server管理中心(eureka-server),微服务群(eureka-provider),调用发起端(consumer)

  1. eureka-server:提供服务注册和发现
  2. eureka-provider:服务提供方将自身服务注册到Eureka,从而使服务消费方能够找到(向注册中心服务注册、服务同步、服务续约)
  3. consumer:服务消费方从Eureka获取注册服务列表,从而能够消费服务(往注册中心获取服务、服务调用、服务下线)

三、示例

  1. 创建eureka-server
    1. 创建一个新的spring initializr服务
    2. 选择集成组件 

       选择组件既是导入了pom中需要依赖的jar

              <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-eureka-server</artifactId>
              </dependency>

      配置配置文件

      server.port = 12345
      spring.application.name = config-center
      
      eureka.instance.hostname:localhost
      #该应用为注册中心,不向自己注册自己
      eureka.client.register-with-eureka=false
      #是否从euruka服务器获取注册信息
      eureka.client.fetch-registry=false
      eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
      
      logging.level.com.netflix.eureka:OFF

      启动类添加eureka-server

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

      启动服务,启动成功,那么eureka-server中心就完成了,在浏览器输入地址,访问http://localhost:12345

      就会出现管理界面,日中Application为空,说明还没有服务注册进来。 

  2. 创建微服务(eureka-provider,也是服务提供者),并注册到eureka-server中
    1. 还是创建springboot工程
    2. 只需要选择eureka客服端即可
    3. 服务是通过web请求,和server之间的联系也是通过web实现的,所以需要引入web依赖
      <?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>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>2.3.3.RELEASE</version>
              <relativePath/> <!-- lookup parent from repository -->
          </parent>
          <groupId>com.sdgtt.com</groupId>
          <artifactId>eureka-client1</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <name>eureka-client1</name>
          <description>Demo project for Spring Boot</description>
      
          <properties>
              <java.version>1.8</java.version>
              <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
          </properties>
      
          <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.boot</groupId>
                  <artifactId>spring-boot-starter-test</artifactId>
                  <scope>test</scope>
                  <exclusions>
                      <exclusion>
                          <groupId>org.junit.vintage</groupId>
                          <artifactId>junit-vintage-engine</artifactId>
                      </exclusion>
                  </exclusions>
              </dependency>
          </dependencies>
      
          <dependencyManagement>
              <dependencies>
                  <dependency>
                      <groupId>org.springframework.cloud</groupId>
                      <artifactId>spring-cloud-dependencies</artifactId>
                      <version>${spring-cloud.version}</version>
                      <type>pom</type>
                      <scope>import</scope>
                  </dependency>
              </dependencies>
          </dependencyManagement>
      
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-maven-plugin</artifactId>
                  </plugin>
              </plugins>
          </build>
      
      </project>
      

       

    4. 配置文件,确认端口和服务应用名称,还有注册中心地址
      server.port = 10001
      spring.application.name= sdgttSpringClient
      
      
      eureka.client.serviceUrl.defaultZone= http://localhost:12345/eureka/
      
      

       

    5. 以两个provide为例,具体代码入口,
      1. provide1
        1. package com.sdgtt.com.eurekaclient1.controller;
          
          import org.springframework.web.bind.annotation.GetMapping;
          import org.springframework.web.bind.annotation.RestController;
          
          /**
           * @author tao
           * @version 2020-09-17 14:43
           */
          @RestController
          public class TestController {
          
              @GetMapping("/hello")
              public Object hello(){
                  return "hello,I'am service provider 1";
              }
          }

           

        2. provide2:

          package com.sdgtt.com.eurekaclient1.controller;
          
          import org.springframework.web.bind.annotation.GetMapping;
          import org.springframework.web.bind.annotation.RestController;
          
          /**
           * @author tao
           * @version 2020-09-17 14:43
           */
          @RestController
          public class TestController {
          
              @GetMapping("/hello")
              public Object hello(){
                  return "hello,I'am service provider 2";
              }
          }

          两个服务返回内容不同。

    6. provider在本地测试过程中可以设置成不同的端口,方便启动,如果是在不同宿主机上启动可以忽略端口问题
    7. 多个provider的spring.application.name必须一致,因为在向server中心注册时,是通过spring.application.name为名注册的
    8. 启动之后就会发现已经有服务注册进来,Application的name就是spring.application.name,两个provide,分别部署在局域网中的两台宿主机上。
  3. 创建消费者(consumer,去请求提供的服务),新建项目。在请求消费端的时候,那么该向哪一个provide发出请求呢,这就需要负载均衡请求各个provide,这里是由ribbon来实现负载均衡的。导入jar包依赖。
    1. 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>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>2.3.3.RELEASE</version>
              <relativePath/> <!-- lookup parent from repository -->
          </parent>
          <groupId>com.sdgtt.com</groupId>
          <artifactId>eureka-consumer</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <name>eureka-consumer</name>
          <description>Demo project for Spring Boot</description>
      
          <properties>
              <java.version>1.8</java.version>
              <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
          </properties>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <version>1.16.6</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-test</artifactId>
                  <scope>test</scope>
                  <exclusions>
                      <exclusion>
                          <groupId>org.junit.vintage</groupId>
                          <artifactId>junit-vintage-engine</artifactId>
                      </exclusion>
                  </exclusions>
              </dependency>
          </dependencies>
      
          <dependencyManagement>
              <dependencies>
                  <dependency>
                      <groupId>org.springframework.cloud</groupId>
                      <artifactId>spring-cloud-dependencies</artifactId>
                      <version>${spring-cloud.version}</version>
                      <type>pom</type>
                      <scope>import</scope>
                  </dependency>
              </dependencies>
          </dependencyManagement>
      
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-maven-plugin</artifactId>
                  </plugin>
              </plugins>
          </build>
      
      </project>
      

       

    2. 配置文件,服务名这里可以随便指定,eureka服务地址还是必须是eureka-server服务的地址。
      server.port = 8080
      spring.application.name= ribbon-consume
      
      
      eureka.client.serviceUrl.defaultZone= http://localhost:12345/eureka/
      

       

    3. spring管理注入RestTemplate,RestTemplate 需要加上@LoadBalanced,申明需要负载均衡
      package com.sdgtt.com.eurekaconsumer.configuration;
      
      import org.springframework.cloud.client.loadbalancer.LoadBalanced;
      import org.springframework.context.annotation.Bean;
      import org.springframework.stereotype.Component;
      import org.springframework.web.client.RestTemplate;
      /**
       * @author tao
       * @version 2020-09-17 15:53
       */
      @Component
      public class BeanConfig {
      
          @Bean
          @LoadBalanced
          public RestTemplate getRestTemplate(){
              return new RestTemplate();
          }
      }
      
    4. 访问consumer的controller入口
      package com.sdgtt.com.eurekaconsumer.controller;
      
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      import org.springframework.web.client.RestTemplate;
      /**
       * @author tao
       * @version 2020-09-17 15:04
       */
      @Slf4j
      @RestController
      @RequestMapping("springboot/ribbon")
      public class ConsumerController {
      
          @Autowired
          private RestTemplate restTemplate;
      
          @GetMapping("/hello")
          public Object hello() {
              String result = restTemplate.getForObject("http://sdgttSpringClient/hello", String.class);
              log.info("sdgttSpringClient服务返回结果为:{}", result);
              return result;
          }
      
      }
      

       

    5. RestTemplate访问的地址不再是具体服务的ip,而是注册在server里的服务名,由eureka-server管理之后,eureka-server去解析ip地址然后请求。
    6. 这时候,查看eureka管理页面,发现consumer启动成功。
    7. 请求consumer服务,请求:http://localhost:8080/springboot/ribbon/hello,得到结果:
    8. 刷新地址请求,发现请求异常
    9. 异常原因是provide服务,主机( DESKTOP-OO7SCB2:sdgttSpringClient:10001)解析失败。原因是这个provide部署在局域网内的另一宿主机上。注册的时候注册的主机名不是ip导致的。
      java.net.UnknownHostException: DESKTOP-OO7SCB2
      	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184) ~[na:1.8.0_151]
      	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_151]
      	at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_151]
    10. 原因:是因为provide在eureka-server注册的时候注册成了宿主机的主机名,改成优先ip就好了,修改方法:修改eureka-server服务配置文件
      server.port = 12345
      spring.application.name = config-center
      
      eureka.instance.hostname:localhost
      #优先使用ip注册
      eureka.instance.prefer-ip-address: true
      #该应用为注册中心,不向自己注册自己
      eureka.client.register-with-eureka=false
      #是否从euruka服务器获取注册信息
      eureka.client.fetch-registry=false
      eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
      
      logging.level.com.netflix.eureka:OFF

       

    11. 如图,两个provide分别在不同的宿主机上启动成功

    12. 在继续访问得到结果,此时说明完成负载均衡

    13. 浏览器结果:

  4. code:https://github.com/foxiaotao/spring-cloud-demo
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值