Ribbon

 

注册中心的高可用(ribbon)

注册中心

多个注册中心开启注册和抓取的功能,

注册中心互为客户端相,相互注册注册中心的服务,

同时抓取的逻辑开启,30秒抓取一次更新的内存map数据,同步到本地合并

服务提供者

如果只在配置时提供一个注册中心地址http://localhost:8888/eureka,在8888没有宕机时,可以实现对该服务的监控管理,同时8889能同步到信息

但是一旦8888宕机,这个服务不会再有后续管理,所以高可用结构中,客户端服务提供者需要同时提供多个注册中心地址,只会使用其中一个,一旦宕机将会自动下沿,使用第二个

搭建步骤

准备2个以上的eureka-server

修改和配置的application.properties

注册中心的服务名称:eurekaserver

端口不能一样 8888 8889

注册中心相互通信开启preferIpAddress

eureka.instance.preferIpAddress=true

客户端角色既要进行注册,也要抓取同步

eureka.client.registerWithEureka=true

eureka.client.fetchRegistry=true

两个注册中心之间相互注册,提供serviceUrl.defaultZone的值

8888

http://localhost:8889/eureka

8889

http://localhost:8888/eureka

eureka-server01

src/main/resourses
application.properties

注册端口defaultZoneeureka-server01的地址

server.port=8888
#Eureka
eureka.instance.hostname=localhost
eureka.instance.preferIpAddress=true
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
eureka.client.serviceUrl.defaultZone=http://localhost:8889/eureka
eureka.server.enable-self-preservation=false

 

eureka-server02

src/main/resourses
application.properties
server.port=8889
#Eureka
eureka.instance.hostname=localhost
eureka.instance.preferIpAddress=true
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka
eureka.server.enable-self-preservation=false

 

备注

两个服务端同时启动,会出现找不到已知服务器的错误提示

Connection refused: connect

提示无法连接

Cannot execute request on any known server

发送注册请求没有任何服务响应

客户端提供注册地址多个,防止其中一个宕机导致服务续约失败

客户端提供注册地址多个,防止其中一个宕机导致服务续约失败

eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka,http://localhost:8889/eureka

 

ribbon组件的使用

服务器内部调用实现负载均衡

能够实现微服务集群中的服务调服务的功能

ribbon客户端搭建

eureka-client01

pom.xml

<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.0</modelVersion><groupId>com.wiscom</groupId>
  <artifactId>eureka-server01</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
  </parent>
  <name>eureka-server01</name>
  <url>http://maven.apache.org</url><properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties><dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Edgware.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>
</project>

 

src/main/resourses

application.properties
server.port=9001
# service name
spring.application.name=service-hi
#Eureka client
eureka.instance.ipAddressPrefer=true
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka,http://localhost:8889/eureka

 

src/main/java

com.wiscom
StarterEurekaClient01.java
package com.wiscom;
​
@SpringBootApplication
//启动eureka注册中心的进程
@EnableEurekaClient
public class StarterEurekaClient01 {
    public static void main(String[] args) {
        SpringApplication.run(StarterEurekaClient01.class, args);
    }
}

 

com.wiscom.controller
HelloController.java
package com.wiscom.controller;
​
@RestController
public class HelloController {
    //通过属性,读取server.port
    @Value("${server.port}")
    private String port;
    @RequestMapping("hello")
    public String sayHi(String name){
        return "hello "+name+",i am from "+port;
    }
}

 

eureka-client02

配置与eureka-client01相同

server.port=9002

 

 

ribbont-client

pom.xml

parent继承springboot

导入springcloud的依赖dependencies

eureka-client依赖

ribbon依赖

 

<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.0</modelVersion><groupId>com.wiscom</groupId>
  <artifactId>ribbont-client</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
  </parent>
  <name>ribbont-client</name>
  <url>http://maven.apache.org</url><properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties><dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
    <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>
  </dependencies>
  <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Edgware.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
  </dependencyManagement>
</project>

 

src/main/resourses

application.properties

开启注册能力,和抓取服务的能力

eureka.client.registerWithEureka=true

eureka.client.fetchRegistry=true

向8888节点的eureka注册中心抓取服务

eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka

server.port=9004
# service name
spring.application.name=service-ribbon
#Eureka client
eureka.instance.ipAddressPrefer=true
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
# 可写多个服务中心
eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka

 

src/main/java

com.wiscom
StarterRibbon.java

ROUNDROBINRULE

轮询逻辑

RANDOMRULE

随机

WeightedResponseTimeRule

根 据响应时间设置权重值,响应时间越慢,权重值越低,反之亦然

package com.wiscom;

@SpringBootApplication
@EnableEurekaClient
public class StarterRibbon {
    public static void main(String[] args) {
        SpringApplication.run(StarterRibbon.class, args);
    }
    //准备一个负载均衡访问的客户端对象
    //RestTemplate @Bean注解实现一个对象由框架维护
    @Bean
    @LoadBalanced //ribbon客户端扫描的负载均衡注解
    public RestTemplate initRestTemplate(){
        return new RestTemplate();
    }
    @Bean
    public IRule initIrule(){
        return new RandomRule();
    }
}

 

com.wiscom.controller
HelloController.java
package com.wiscom.controller;

@RestController
public class HelloController {
    //注入service实现底层访问服务的方法
    @Autowired
    private HelloService helloService;
    @RequestMapping("sayHi")
    public String sayHi(String name){
        return "RIBBON:"+helloService.sayHi(name);
    }
}

 

com.wiscom.service
HelloService.java
package com.wiscom.service;

@Service
public class HelloService {
    //注入RestTemplate
    @Autowired
    private RestTemplate client;
    public String sayHi(String name) {
        //访问service-hi的服务提供者集群,实现负载均衡
        //直接在代码中由于ribbon客户端进程的存在,由于创建
        //RestTemplate使用了LoadBalanced注解,直接访问服务名称
        String result = 
            client.getForObject(
            "http://service-hi/hello?name="
            +name, String.class);
        //9001/9002 hello name i am from 9001/9002
        return result;
    }
}

 

测试结果:

客户端访问9004的ribbon工程

实际内部做了负载均衡

服务器内部访问后端服务service-hi的提供者9001/9002

 

负载均衡逻辑

ROUNDROBINRULE 轮询逻辑

RANDOMRULE 随机、

WeightedResponseTimeRule 根据响应时间设置权重值,响应时间越慢,权重值越低,反之亦然

        @Bean
        public IRule initIrule(){
            return new RandomRule();
        }

 

RIBBON的拦截逻辑

ribbon内嵌拦截器(LoadBalancerInterceptor

获取原有url

解析服务名称

获取服务名称对应的mapper数据

根据负载均衡从服务实例列表中选取一个

拼接地址

posted @ 2020-08-19 20:27  minnersun  阅读(207)  评论(0编辑  收藏  举报