微服务系列文章目录
- [深入微服务-服务注册与发现 SpringCloud Eureka之基础]()
如果本文对你们的开发之路有所帮助,请帮忙点个赞,您的支持是我坚持写博客的动力
【面试相关】微信关注【Java从零学架构】,后台回复【面试题目】自取
前言
本系列带着大家深入微服务 Spring体系的各个框架的底层原理。上一篇文章介绍了SpringCloud 调用组件Feign,本节将带着大家掌握微服务服务注册与发现框架 Spring Eureka
什么是服务注册与发现?
- 服务注册需要解决的问题:当微服务相互调用的时候,A服务调用B服务,A服务需要获取B服务的调用地址这个就是服务发现
- 服务注册:服务注册与发现中有一个注册中心(Service Registry),当接入的客户端(服务提供方)启动的时候会把自己的服务url以及端口号等信息注册到注册中心(Service Registry)上
- 服务发现:服务消费方调用服务提供方,需要从注册中心(Service Registry)获取服务实际的通信地址,实现rpc远程调用
- 目前市面上服务注册与发现框架有:Eureka、Consul、Nacos、etcd、Dubbo(注册中心为Zookeeper)
服务注册与发现框架
框架 | 功能 | CAP原则 | 通信协议 | 一致性保障 | 开发语言 |
---|---|---|---|---|---|
Zookeeper | 分布式协调工具,强一致性,主节点宕机选举过程会有服务不可用情况 | CP | 基于TCP/IP协议,sdk实现 | paxos | Java |
Etcd | 分布式键值对存储系统,服务注册需要其他框架支持 | CP/AP | http/grpc | raft | go |
Eureka | 支持集群部署,底层注册表结构为Map存储,1.0暂停维护 | AP | http | Java | |
Consul | 支持多数据中心,UI界面优秀 | CP | http(s)/dns | raft | go |
Nacos | 性能较高,同时支持配置中心 | AP/CP | http | Distro/ Raft | java |
SpringCloud 集成Eureka
注册中心搭建
1.引入Maven库
代码如下(示例):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2.开启注册中心功能
@EnableEurekaServer 注解:启动EurekaServer
@EnableEurekaServer
@SpringBootApplication
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}
配置文件application.yaml
server:
port: 8007 # server 端口号
eureka:
instance:
hostname: 127.0.0.1 # eureka 注册的主机地址
client:
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
register-with-eureka: false # 指定是否从注册中心获取服务(注册中心不需要开启)
fetch-registry: false # 指定是否注册到注册中心(注册中心不需要开启)
服务提供方
1、引入Maven
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、集成服务
1)集成启动类
@EnableEurekaClient 注解为客户端开启服务注册与发现功能
@SpringBootApplication
@EnableEurekaClient
public class ProviderApplication{
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
2)配置注册Eureka相关配置信息
server:
port: 8001
spring:
application:
name: provider-server
eureka:
client:
service-url:
defaultZone: http://localhost:8007/eureka ##填写注册中心地址
register-with-eureka: true # 指定是否从注册中心获取服务
fetch-registry: true #指定是否注册到注册中心
3)提供数据服务接口
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "hello";
}
}
服务消费者
1)集成启动类
@EnableEurekaClient 注解为客户端开启服务注册与发现功能
@LoadBalanced 启用服务负载均衡功能
@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication{
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
2)配置注册Eureka相关配置信息
server:
port: 8002
spring:
application:
name: consumer-server
eureka:
client:
service-url:
defaultZone: http://localhost:8007/eureka ##填写注册中心地址
register-with-eureka: true # 指定是否从注册中心获取服务
fetch-registry: true #指定是否注册到注册中心
3)服务调用
@RestController
@Slf4j
public class DataController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/getHello")
public String getHello() {
// rpc调用服务提供方的接口
String providerUrl = "http://provider-server/hello";
String result = restTemplate.getForObject(providerUrl, String.class);
log.info("服务调用结果 {}",result)
return result;
}
}
Eureka 集成认证中心
1)Maven依赖
<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-security</artifactId>
</dependency>
修改application.yaml
server:
port: 8002
spring:
application:
name: consumer-server
security: #配置SpringSecurity登录用户名和密码
user:
name: user
password: password
eureka:
client:
service-url:
defaultZone: http://localhost:8007/eureka ##填写注册中心地址
register-with-eureka: true # 指定是否从注册中心获取服务
fetch-registry: true #指定是否注册到注册中心
3)Security配置类
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().disable();
http.headers().frameOptions().disable();
}
}