Eureka注册中心集群
为什么要集群
如果只有一个注册中心服务器,会存在单点故障,不可以高并发处理所以要集群。
如何集群
准备三个EurekaServer 相互注册,也就是说每个EurekaServer都需要向所有的EureakServer注册,包括自己 ,每个EurekaServer即充当了服务端,也充当了客户端。咱们的其他微服务(order,user)只需要把注册地址指向所有的EurekaServer就可以了。
代码实现:
此处采用的是一个Eureka模块,配置多份yml文件,达到集群的效果 。
启动类
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @ClassName EurekaStart
* @Author 23
* @Date 2024/7/10 19:12
* @Version 1.0
* @Description TODO
**/
@SpringBootApplication
@EnableEurekaServer
public class EurekaStart {
public static void main(String[] args) {
SpringApplication.run(EurekaStart.class,args);
}
}
yml
spring:
profiles:
active: peer3
---
spring:
profiles: peer1
application:
name: Eureka1
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:10070/eureka/
server:
port: 10070
---
spring:
profiles: peer2
application:
name: Eureka2
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:10071/eureka/
server:
port: 10071
---
spring:
profiles: peer3
application:
name: Eureka3
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:10072/eureka/
server:
port: 10072
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>
<parent>
<groupId>org.example</groupId>
<artifactId>Springcloud-Netflix</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>Eureka-Service</artifactId>
<packaging>jar</packaging>
<name>Eureka-Service</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>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<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>
</dependency>
<!-- Eureka服务端支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
服务负载均衡
为什么需要负载均衡
为了提供并发量,有时同一个服务提供者可以部署多个(商品服务)。这个客户端在调用时要根据一定的负责均衡策略完成负载调用。
服务提供者配置
spring:
profiles:
active: order2
---
server:
port: 10010
spring:
profiles: order1
application:
name: order-service
eureka:
client:
service-url:
defaultZone: http://localhost:10072/eureka
instance:
prefer-ip-address: true
---
server:
port: 10012
spring:
profiles: order2
application:
name: order-service
eureka:
client:
service-url:
defaultZone: http://localhost:10072/eureka
instance:
prefer-ip-address: true
常见的负载均衡实现技术
Ribbon
通过RestTmplate,以url完成服务的调用
代码实现(服务消费端):
package org.example.Controller;
import org.example.domain.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
/**
* @ClassName UserController
* @Author 23
* @Date 2024/7/10 18:52
* @Version 1.0
* @Description TODO
**/
@RestController
@RequestMapping("/User")
public class UserControllerrlb {
@Autowired
private RestTemplate restTemplate;
// @Autowired
// private DiscoveryClient discoveryClient;
@GetMapping("/getOrder/{id}")
public List<Order> getOrderById(@PathVariable("id") Integer id) {
// Order[] order = restTemplate.getForObject("http://localhost:10010/OrderService/user/" + id, Order[].class);
// return Arrays.asList(order);
// List<ServiceInstance> instances=discoveryClient.getInstances("order-service");//通过服务的名字去获取服务实例
// ServiceInstance serviceInstance=instances.get(0);//定死只获取第一个服务实例对象
// String ip=serviceInstance.getHost();//获取服务对象ip
// int port=serviceInstance.getPort();//获取获取的实例对象的服务端口号
Order[] orders=restTemplate.getForObject("http://Order-Service/OrderService/user/"+id,Order[].class);
return Arrays.asList(orders);
}
}
Ribbon负载均衡调用
Ribbon是Netflix发布的云中间层服务开源项目,主要功能是提供客户端负载均衡算法。Ribbon客户端组件提供一系列完善的配置项,如,连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中列出load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。Ribbon是一个客户端负载均衡器,它可以按照一定规则来完成一种服务多个服务实例负载均衡调用,这些规则还支持自定义。
原理图:
OpenFeign负载均衡
OpenFeign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的接口模板(上面标的有访问地址),通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。而OpenFeign则会完全代理(动态代理)HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。
负载均衡策略
IRule
通过配置不同IRule的子类,可以选择不同负载均衡策略,也就是从服务列表以特定策略选择一个服务来完成调用。当然也可以自定义。所以负载均衡策略可以分为内置和自定义。
内置负载均衡策略