Eureka
Eureka Server注册中心
简单的高可用,开启3个eureka 相互注册到对方上。
pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
yml (这里,的另外2个eureka 都填写对方的端口)
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8763/eureka/
register-with-eureka: false #不把自己注册到client上
server:
# 自我保护机制,一个服务开关太过频繁,注册中心就一段时间内直接认为你是在的,开发环境下设置成false(实际环境要打开),防止服务挂掉,注册还在
enable-self-preservation: false
spring:
application:
name: eureka
server:
port: 8762
@SpringBootApplication
@EnableEurekaServer
public class Eureka1Application {
public static void main(String[] args) {
SpringApplication.run(Eureka1Application.class, args);
}
}
Eureka Client 服务注册
pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
yml
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
spring:
application:
name: client-user # 服务名称
启动类
@SpringBootApplication
@EnableDiscoverClient
public class Eureka1Application {
public static void main(String[] args) {
SpringApplication.run(Eureka1Application.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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gray</groupId>
<artifactId>server-register</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server-register</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-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>${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>
相互通信
1、RestTemplate (通过发送url直接获取返回值)
<!-- @Slf4j 需要引的包 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
@RestController
public class HelloController {
@RequestMapping("/hello")
public String getHello(){
return "Hello world";
}
}
@RestController
@Slf4j
public class HelloClientController {
@GetMapping("/client-hello")
public String getHello(){
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://localhost:8080/hello",String.class);
log.info("response={}",response);
return response;
}
}
2、LoadBalancerClient (通过服务器id获取服务器信息)
@RestController
@Slf4j
public class HelloClientController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/client-loadBalancer")
public String getLoadBalancer(){
RestTemplate restTemplate = new RestTemplate();
ServiceInstance serviceInstance = loadBalancerClient.choose("EUREKACLIENT");
String url = String.format("http://%s:%s",serviceInstance.getHost(),serviceInstance.getPort() + "/hello");
String response = restTemplate.getForObject(url,String.class);
log.info("response={}",response);
return response;
}
}
3、@LoadBalanced
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
@RestController
@Slf4j
public class HelloClientController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/restTemp")
public String getRestTemp(){
String response = restTemplate.getForObject("http://EUREKACLIENT/hello",String.class);
log.info("response={}",response);
return response;
}
}
Ribbon 负载均衡器
涉及使用:RestTemplate、Feign、Zuul (客户端自己的负载均衡)
功能:服务发现(通过服务名字找到所有实例)、服务选择(依据规定的方式选择实例)、服务监听(检查实效的服务,高效剔除)
客户端指定添加均衡策略,请求localhost:8080/restTemp (服务得开启多个,这里是放在调用方客户端的),product是服务器名称
yml
1、随机规则(RandomRule)
在rule的choose的时候 使用一个所有服务列表中取随机数去可用服务(upList)中取可用的服务,如果取到的服务不可用或者无此服务。
2、线性轮训规则(RoundRobinRule)
线性轮询和RandomRule相似,循环条件以外增加了10次的轮询限制,如果10次没有获取到可用的服务,则返回 No available alive serivces after 10 tries from load balancer.....
3、重试规则(RetryRule)
RetryRule增加了一个重试机制,此机制默认使用 RoundRobinRule规则来获取服务,通知定义了一个重试时间(maxRetryMillis),如果在重试时间内没有获取到可用的服务,则重复进行获取,如果超出重试时间还未获取到则返回null。
4、WeightedResponseTimeRule(反馈权重规则)
该策略主要是对RoundRobinRule规则的扩展,根据实例的运行情况计算权重,并根据权重来选择实例,以达到最优的分配效果
5、ClientConfigEnableRoundRobinRule
内部使用RoundRobinRule规则来实现策略,但是经常继承这个类来实现高级策略的制定
6、BestAvailableRule(选择最优的服务)
继承了CIientConfigEnableRoundRobinRule规则,在实现时注入了负载均衡器的统计对象LoadBalacneStats ,同时在选择实例的时候利用LoadBalaceStats来统计信息来来选择满足要求的实例
7、PredicateBasedRule(基于预先判断的测试)
这是一种过滤清单的一种策略,在选择服务的时候先将获取到的服务清单通过Predicate配置的过滤条件来过滤一部分服务,然后再通过线性轮训的方式来进行服务选择。
8 AvailabilityFilteringRule(可用性过滤的规则)
这是可用性过滤的策略,就是在选择的时候,过滤所有的Server都是可以服务正常的Server。
9 ZoneAvoidanceRule
域的过滤器,这个其实是ZoneAvoidancePredicate和AvailabilityPredicate的组合过滤器,同时过滤所在的域和可用性的过滤器。
springcloud方法
提供服务
pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
yml
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
spring:
application:
name: product
server:
port: 8081
启动类
@SpringBootApplication
@EnableDiscoveryClient
public class UserClientApplication {
public static void main(String[] args) {
SpringApplication.run(UserClientApplication.class, args);
}
}
开放方法
@RestController
public class HelloController {
@Value("${server.port}")
private String msg;
@RequestMapping("/hello")
public String getHello(){
return "Hello world port = " + msg;
}
}
使用服务
pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</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-web</artifactId>
</dependency>
yml
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
spring:
application:
name: product-client
CLIENT:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ProductClientApplication {
public static void main(String[] args) {
SpringApplication.run(ProductClientApplication.class, args);
}
}
调用接口
@FeignClient(name = "product")
public interface UserClientBase {
@RequestMapping("/hello")
String getHello();
}
具体调用
@RestController
public class Hello {
@Autowired
private UserClientBase userClientBase;
@GetMapping("/getMsg")
public String getMsg(){
return userClientBase.getHello();
}
}