注册中心就是一个统一管理管理不同的微服务项目的ip地址的一个服务, 不同的服务将自己的服务注册到注册中心上, 消费者会从注册中心上去寻找自己需要的RPC远程调用地址之后, 最终以HTTPClient技术实现远程调用.
1. 注册中心环境搭建
新建eureka项目
依赖环境
org.springframework.boot
spring-boot-starter-parent
2.0.1.RELEASE
org.springframework.cloud
spring-cloud-dependencies
Finchley.M7
pom
import
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
yml配置
###服务端口号
server:
port: 8100
###eureka 基本信息配置
eureka:
instance:
###注册到eurekaip地址
hostname: 127.0.0.1
client:
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
register-with-eureka: false
fetch-registry: false
创建启动类
@EnableEurekaServer
@SpringBootApplication
public class AppEureka {
public static void main(String[] args) {
SpringApplication.run(AppEureka.class, args);
}
}
2.注册服务提供者
新建Provider项目
添加依赖
org.springframework.boot
spring-boot-starter-parent
2.0.1.RELEASE
org.springframework.cloud
spring-cloud-dependencies
Finchley.M7
pom
import
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
spring-milestones
Spring Milestones
https://repo.spring.io/libs-milestone
false
yml配置
server:
port: 8000
spring:
application:
name: app-provider
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
register-with-eureka: true
fetch-registry: true
创建启动类
@SpringBootApplication
@EnableEurekaClient
public class App {
// @EnableEurekaClient 将当前服务注册到eureka上
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
刷新eureka会看到
Application为
spring.application.name: app-provider
2.注册服务消费者
新建custom项目
添加依赖
org.springframework.boot
spring-boot-starter-parent
2.0.1.RELEASE
org.springframework.cloud
spring-cloud-dependencies
Finchley.M7
pom
import
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
spring-milestones
Spring Milestones
https://repo.spring.io/libs-milestone
false
yml配置
server:
port: 8001
spring:
application:
name: app-customer
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
register-with-eureka: true
fetch-registry: true
消费者Controller
@RestController
public class OrderControler {
// RestTemplate 是有SpringBoot Web组件提供 默认整合ribbon负载均衡器
// rest方式底层是采用httpclient技术
@Autowired
private RestTemplate restTemplate;
/**
* 在SpringCloud 中有两种方式调用 rest、fegin(SpringCloud)
*
* @return
*/
@RequestMapping("/getOrder")
public String getOrder() {
// 有两种方式,一种是采用服务别名方式调用,另一种是直接调用 使用别名去注册中心上获取对应的服务调用地址
String url = "http://127.0.0.1:8000/getMember";
String result = restTemplate.getForObject(url, String.class);
System.out.println("调用服务result:" + result);
return result;
}
}
rest底层使用的是httpclient技术来实现远程调用String url = "http://127.0.0.1:8000/getMember"
, 这个直接走的是ip地址. 不会走注册中心
创建启动类
@SpringBootApplication
@EnableEurekaClient
public class AppOrder {
public static void main(String[] args) {
SpringApplication.run(AppOrder.class, args);
// 如果使用rest方式以别名方式进行调用依赖ribbon负载均衡器 @LoadBalanced
// @LoadBalanced就能让这个RestTemplate在请求时拥有客户端负载均衡的能力
}
// 解决RestTemplate 找不到原因 应该把restTemplate注册SpringBoot容器中 @bean
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}
这样虽然实现了rpc远程调用, 但是, 远程调用直接走的是ip地址, 实际上, 我们的调用地址应该从注册中心上获取
String url = "http://127.0.0.1:8000/getMember"
应该改为String url = "http://api-provider/getMember"
, api-provider 为注册到注册中心的服务名称, 底层会把它转为IP地址.
@RequestMapping("/getOrder")
public String getOrder() {
String url = "http://app-provider/getMember";
String result = restTemplate.getForObject(url, String.class);
System.out.println("调用服务result:" + result);
return result;
}
此外还有一个问题, 如果使用rest方式以别名方式进行调用, 需要依赖ribbon负载均衡器 @LoadBalanced,
@LoadBalanced就能让这个RestTemplate在请求时拥有客户端负载均衡的能力, rest底层是依赖ribbon的.
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
@LoadBalanced注解用于实现负载均衡, 其实现负载均衡的原理是. 当服务注册到注册中心上时, 注册中心上包含该服务的ip地址和服务名称, 消费者根据服务名称拿到对应的IP地址, 饭后在本地使用ribbon来实现负载均衡策略, 一半策略就是轮训, 权重等.ribbon默认是轮训机制.
Eureka高可用原理
默认情况下Eureka是让服务注册中心,不注册自己
###因为该应用为注册中心,不会注册自己
register-with-eureka: true
###不需要去注册中心上检索服务
fetch-registry: true
Eureka高可用实际上将自己作为服务向其他服务注册中心注册自己,这样就可以形成一组相互注册的服务注册中心,从而实现服务清单的互相同步,达到高可用效果。
现在有两个服务8100和9100两个注册中心
在9100的服务上将8100注册到注册中心
###服务端口号
server:
port: 9100
spring:
application:
name: app-eureka
eureka:
client:
serviceUrl:
##注册地址, 如果是超过两个, 除了自己的不写, 其他的都写
defaultZone: http://${eureka.instance.hostname}:8100/eureka/
####因为自己是注册中心,是否需要将自己注册给自己的注册中心(集群的时候是需要是为true)
register-with-eureka: true
###因为自己是注册中心, 不需要去检索服务信息
fetch-registry: true
在8100的服务上将9100注册到注册中心
server:
port: 8100
spring:
application:
name: app-eureka
eureka:
client:
serviceUrl:
##注册地址, 如果是超过两个, 除了自己的不写, 其他的都写
defaultZone: http://${eureka.instance.hostname}:9100/eureka/
####因为自己是注册中心,是否需要将自己注册给自己的注册中心(集群的时候是需要是为true)
register-with-eureka: true
###因为自己是注册中心, 不需要去检索服务信息
fetch-registry: true
定义服务名称, 多个注册中心的名称一定要一样, 即都要是app-eureka
接下来启动消费者和生产者, 配置yml, 设置两台eureka注册中心的地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka,http://localhost:9100/eureka
注意: 此时你会发现只有一台eureka服务, 9100或者8100有对应的消费者和生产者的信息, 并不是两台全都有. 类似于一主一备 当其中一台挂掉之后, 注册的信息会被自动转移到另外一台服务上.