Spring cloud eureka feign ribbon

Ribbon提供一种客户端的负载均衡技术,实现和集群中的服务通信。包含了三种组件
[list]
[*]Rule 一个逻辑组件用来确定从服务列表中获取哪一个服务
[*]Ping 运行在后台的组件,用来确定服务是否可用
[*]ServerList 一个后台线程,可以以特定的频率来刷新和过滤服务,可以是静态的也可以是动态的
[/list]

这些组件既可以通过API方式设定,也可以在配置文件中设定在通过反射方式创建。

1.Common rules

[*]RoundRobinRule 这个策略通过简单的轮询策略来选择服务,常常作为默认策略或者是高级策略的后备策略使用
[*]AvailabilityFilteringRule 这个策略将跳过那些被认为路由断开的或者是高并发连接数的server instance
[*]WeightedResponseTimeRule 这个策略通过利用服务的平均响应时间来得到一个权重,响应时间越长的权重越小,依据权重再随机的挑选一个策略


2.ServerList

[*]Adhoc static server list 利用BaseLoadBalancer.setServersList()API设定一个静态的服务列表
[*]ConfigurationBasedServerList 默认的ServerList实现方式,可以通过下面的方式设定

sample-client.ribbon.listOfServers=www.microsoft.com:80,www.yahoo.com:80,www.google.com:80

[*]DiscoveryEnabledNIWSServerList 这中ServerList实现方式从 Eureka client中获取服务列表,在spring boot程序中,当Eureka相应的jar在classpath中存在,会默认采用这种策略

3.ServerListFilter
该组件是DynamicServerListLoadBalancer用来在ServerList过滤服务的组件,有以下两种实现方式

[*]ZoneAffinityServerListFilter 过滤掉那些和client不在同一个zone的服务,除非client所在的zone中没有可用的server,通过以下方式可以启用
myclient.ribbon.EnableZoneAffinity=true

[*]ServerListSubsetFilter 这个过滤器确保client只能访问到服务集合中的一个特定子集,并能周期性的不好用的服务替换掉,通过以下方式可以启用

myClient.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
# the server must register itself with Eureka server with VipAddress "myservice"
myClient.ribbon.DeploymentContextBasedVipAddresses=myservice
myClient.ribbon.NIWSServerListFilterClassName=com.netflix.loadbalancer.ServerListSubsetFilter
# only show client 5 servers. default is 20.
myClient.ribbon.ServerListSubsetFilter.size=5



例子
[*]1. Eureka server
核心是在正常的Spring boot程序中加入spring-cloud-starter-eureka-server依赖,在启动类中加入@EnableEurekaServer 注解
[*]代码结构:

[img]http://dl2.iteye.com/upload/attachment/0123/0198/ee2df8a8-a55d-3cac-a0d5-aaf59abb97cc.png[/img]


[*]启动类

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekaServiceApplication {

public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class, args);
}
}



[*]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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>eureka-service</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.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR5</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>

<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>

</project>



[*]应用配置信息

server.port=8761

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF


[*]2.Eureka client(即user server端)
核心是在正常的Spring boot程序中加入spring-cloud-starter-eureka依赖,在启动类中加入@EnableDiscoveryClient注解

[*]代码结构:


[img]http://dl2.iteye.com/upload/attachment/0123/0200/87a1db06-766b-3277-bd26-60a6717814b2.png[/img]

[*]启动类

package hello;

import java.util.Arrays;
import java.util.List;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableDiscoveryClient
@SpringBootApplication
public class SayHelloApplication {

private static Logger log = LoggerFactory.getLogger(SayHelloApplication.class);

@RequestMapping(value = "/greeting")
public String greet() {
log.info("Access /greeting");

List<String> greetings = Arrays.asList("Hi there", "Greetings", "Salutations");
Random rand = new Random();

int randomNum = rand.nextInt(greetings.size());
return greetings.get(randomNum);
}

public static void main(String[] args) {
SpringApplication.run(SayHelloApplication.class, args);
}
}



[*]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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>hello</groupId>
<artifactId>say-hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>say-hello</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<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-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


</project>




[*]应用配置信息(因为在一台机器上模拟server cluster 所以用了三个profile 分别对应三个port)

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
leaseRenewalIntervalInSeconds: 10
metadataMap:
instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}}

endpoints:
restart:
enabled: true
shutdown:
enabled: true
health:
sensitive: false

---
spring:
application:
name: say-hello
profiles: one
server:
port: 8090

---
spring:
application:
name: say-hello
profiles: two
server:
port: 9092

---
spring:
application:
name: say-hello
profiles: three
server:
port: 9999



[*]3.User client(调用注册到Eureka server中的Eureka client)
核心是在正常的Spring boot程序中加入spring-cloud-starter-eureka、spring-cloud-starter-feign、spring-cloud-starter-ribbon依赖,在启动类中加入@EnableFeignClients、@RibbonClient(name = "say-hello")注解

[*]代码结构:


[img]http://dl2.iteye.com/upload/attachment/0123/0202/f67d8f26-214e-3f58-94ea-7abe8ea74c78.png[/img]


[*]启动类

package hello;

import static org.springframework.web.bind.annotation.RequestMethod.GET;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
@RibbonClient(name = "say-hello")
@EnableFeignClients
public class UserApplication {

@Autowired
HelloClient client;

@RequestMapping("/greeting")
public String hello() {
return client.greet();
}

public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}

@FeignClient(name = "say-hello")
interface HelloClient {
@RequestMapping(value = "/greeting", method = GET)
String greet();
}
}



FeignClient、RibbonClient中的service id要和Eureka client配置信息中的spring.application.name的值保持一致


[*]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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>hello</groupId>
<artifactId>user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>user</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>

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

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR5</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>

<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

</project>



[*]应用配置信息

spring:
application:
name: user

server:
port: 8888

say-hello:
ribbon:
ServerListRefreshInterval: 15000

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
leaseRenewalIntervalInSeconds: 10
metadataMap:
instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}}



三、启动
按下面的顺序启动
Eureka server ->Eureka client(say-hello)-> user client(user)
其中Eureka client 启动时分别用
--spring.profiles.active=one
--spring.profiles.active=two
--spring.profiles.active=three
启动三个服务,注册到eureka中

等所有应用都启动后通过界面访问http://localhost:8888/greeting,可以正常访问Eureka client中的方法返回值,整个流程是 界面访问 user client 工程中的hello方法,user client通过@FeignClient中指定的service id从Eureka server中获取到注册的 say-hello instance,因为我们注册到Eureka中的say-hello实例有三个,此处会利用Ribbon的RoundRobinRule规则获取一个实例,调用对应的greet()方法,返回调用结果给 user client,最终返回界面

[img]http://dl2.iteye.com/upload/attachment/0123/0204/eca24b95-f28b-3f46-bd90-48f58cf4eae9.png[/img]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值