Eureka实现了服务的自动注册、发现、状态监控
1、原理图
- Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址
- 服务提供者:启动后向Eureka注册自己信息
- 消费者:向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新
- 心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态
2、编写EurekaServer注册中心
编写启动类:
@SpringBootApplication
@EnableEurekaServer // 声明这个应用是一个EurekaServer
public class EurekaDemoApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaDemoApplication.class, args);
}
}
在application.yml中编写配置:
server:
port: 666 # 端口
spring:
application:
name: eureka-server # 应用名称,会在Eureka中显示
eureka:
client:
register-with-eureka: false # 是否注册自己的信息到EurekaServer,默认是true
fetch-registry: false # 是否拉取其它服务的信息,默认是true
service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址
defaultZone: http://127.0.0.1:${server.port}/eureka
3、将user-service服务提供者注册到Eureka
首先要在user-service中添加maven依赖:
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
在启动类上开启客户端功能,通过添加@EnableDiscoveryClient来开启Eureka客户端功能:
@SpringBootApplication
@MapperScan("com.sun.mapper")
@EnableDiscoveryClient // 开启EurekaClient功能
public class UserServiceDemoApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceDemoApplication.class, args);
}
}
在application.yml中编写配置:
server:
port: 777
spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis
username: root
password: root
application:
name: user-service # 应用名称
mybatis:
type-aliases-package: com.sun.user.pojo
eureka:
client:
service-url: # EurekaServer地址
defaultZone: http://127.0.0.1:666/eureka
instance:
prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
4、消费者从Eureka注册中心获取服务
首先要在consumer-service中添加maven依赖
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
在启动类开启Eureka客户端
@SpringBootApplication
@EnableDiscoveryClient // 开启Eureka客户端
public class UserConsumerDemoApplication {
//RestTemplate模板工具类,对http客户端进行了封装,实现了对象与json的序列化和反序列化
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
public static void main(String[] args) {
SpringApplication.run(UserConsumerDemoApplication.class, args);
}
}
在application.yml中编写配置:
server:
port: 888
spring:
application:
name: consumer # 应用名称
eureka:
client:
service-url: # EurekaServer地址
defaultZone: http://127.0.0.1:666/eureka
instance:
prefer-ip-address: true # 当其它服务获取地址时提供ip而不是hostname
ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
Service代码,用DiscoveryClient类的方法,根据服务名称,获取服务实例:
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;// Eureka客户端,可以获取到服务实例信息
public List<User> queryUserByIds(List<Long> ids) {
List<User> users = new ArrayList<>();
// 根据服务名称,获取服务实例
List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
// 因为只有一个UserService,因此直接get(0)获取
ServiceInstance instance = instances.get(0);
// 获取ip和端口信息
// String baseUrl = "http://localhost:777/user/";
String baseUrl = "http://"+instance.getHost() + ":" + instance.getPort()+"/user/";
ids.forEach(id -> {
// 测试多次查询,
users.add(this.restTemplate.getForObject(baseUrl + id, User.class));
// 每次间隔500毫秒
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return users;
}
}
这只是一个注册中心,一个服务提供者,一个消费者。之后可以做注册中心的集群,做user-service的集群,此时获取的服务列表中就会有多个,到底该访问哪一个呢,就可以做负载均衡Robbin。