注册中心
Eureka能够自动注册并发现微服务,然后对服务的状态、信息进行集中管理。当我们需要获取其他服务的信息时,只需要向Eureka进行查询。
a: 微服务1 b: 微服务2 c: 微服务3 E: Eureka注册中心
a -> E: 注册 b -> E: 注册 c -> E: 注册
|
依赖
父项目
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2024.0.0</version> <type>pom</type> <scope>import</scope> </dependency>
|
Eureka模块
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
|
配置
eureka: fetch-registry: false registry-with-eureka: false service-url: defaultZone: http://yourhost:port/eureka
|
@SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }
|
注册服务
首先在需要注册的微服务下导入Eureka依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
|
然后修改配置appllication.yml
:
spring: application: name: yourservice eureka: client: service-url: defaultZone: http://yourhost:port/eureka
|
服务发现
注册RestTemplate
@Configuration public class BeanConfiguration {
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
|
使用spring-application-name代替URL
@Override public UserBorrowDetail getUserBorrowDetailByUid(int uid) { List<Borrow> borrow = borrowMapper.getBorrowByUid(uid); RestTemplate restTemplate = new RestTemplate(); User user = restTemplate.getForObject("http://userservice/user/"+uid, User.class); List<Book> bookList = borrow .stream() .map(b -> restTemplate.getForObject("http://bookservice/book/"+b.getBid(), Book.class)) .collect(Collectors.toList()); return new UserBorrowDetail(user, bookList); }
|
负载均衡
同一个服务可以注册多个端口,Eureka会为同一服务的多个端口分别进行注册。
使用上面的代码,Eureka会自动地均衡分发请求到不同端口上。
负载均衡保证了服务的安全性,只要不是所有端口的微服务都宕机,Eureka就能够分配请求到可用的端口。
Eureka高可用集群
E: Eureka高可用集群 E: { E1: Eureka服务器1 E2: Eureka服务器2 E3: Eureka服务器3
E1 -> E2 E2 -> E3 E3 -> E1 }
a: 微服务1 b: 微服务2 c: 微服务3 a -> E: 注册 b -> E: 注册 c -> E: 注册
|
编写多个application.yml
server: port: 8801 spring: application: name: eurekaserver eureka: instance: hostname: eureka01 client: fetch-registry: false service-url: defaultZone: http://eureka01:8802/eureka
server: port: 8802 spring: application: name: eurekaserver eureka: instance: hostname: eureka02 client: fetch-registry: false service-url: defaultZone: http://eureka01:8801/eureka
|
微服务写入所有Eureka服务器的地址
eureka: client: service-url: defaultZone: http://localhost:8801/eureka, http://localhost:8802/eureka
|
LoadBalance 随机分配
默认的LoadBalance是轮询模式,想修改为随机分配,需要修改LoadBalancerConfig
(注意,不需要@Configuration
注解)并在BeanConfiguration
中启用
public class LoadBalancerConfig { @Bean public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory){ String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name); } }
@Configuration @LoadBalancerClient(value = "userservice", configuration = LoadBalancerConfig.class) public class BeanConfiguration {
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
|
OpenFeign 更方便的HTTP客户端请求工具
OpenFeign和RestTemplate有一样的功能,但是使用起来更加方便
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
|
使用方法与Mybatis非常类似。
- 首先,启用OpenFeign
@SpringBootApplication @EnableFeignClients public class SomeApplication { public static void main(String[] args) { SpringApplication.run(SomeApplication.class, args); } }
|
- 接下来注册一个
interface
@FeignClient("userservice") public interface UserClient {
@RequestMapping("/user/{uid}") User getUserById(@PathVariable("uid") int uid); }
|
- 直接注入使用
@Resource UserClient userClient;
@Override public UserBorrowDetail getUserBorrowDetailByUid(int uid) {
RestTemplate template = new RestTemplate(); User user = template.getForObject("http://userservice/user/"+uid, User.class); User user = userClient.getUserById(uid);
}
|