- 1、 什么是微服务注册中心?
- 图示
- 1.1 基本介绍
- 1.2 为什么要用微服务注册中心?
- 1.3 主流的注册中心
- 2、 分布式应用知识 CAP 理论知识
- 2.1 CAP 定理
- 2.2 C、A、P
- 2.3 总结
- 3、 分布式系统 CAP 原理常见面试题和注册中心选择
- 3.1 注册中心选择
- 3.2 结论
- 4、 SpringCloud 微服务核心组件 Eureka 介绍和闭源后影响
- 5、 服务注册和发现之 Eureka Server 搭建(Eureka服务端搭建)
- 6、 服务注册和发现之 Eureka Client 搭建商品服务(Eureka客户端搭建)
- 7、 Eureka 服务注册中心配置控制台问题处理
- 理解注册中心:服务管理;核心是有个服务注册表;心跳机制动态维护。
- 服务提供者 provider:启动的时候向注册中心上报自己的网络信息
- 服务消费者 consumer:启动时同样向注册中心上报自己的网络信息,拉取 provider 的相关网络信息
- 各个微服务与注册中心使用一定机制(例如心跳)通信。如果注册中心与某微服务长时间无法通信,就会注销该实例。
- 微服务应用和机器越来越多,调用方需要知道接口的网络地址,如果靠配置文件的方式去维护网络地址,对于动态新增机器会很麻烦,维护难度大。
- 而使用注册中心时:各个微服务在启动时,将自己的网络地址等信息注册到注册中心,注册中心存储这些数据。服务消费者(consumer)从注册中心查询服务提供者(provider)的地址,并通过该地址调用服务提供者(provider)的接口。
zookeeper、eureka、consul、etcd 等。
2、 分布式应用知识 CAP 理论知识 2.1 CAP 定理指的是在一个分布式系统中,Consistency(一致性)、Availability(可用性)、PartitionTolerance(分区容错性),三者不可同时获得。
2.2 C、A、P- 一致性(C):在分布式系统中的所有数据备份,在同一时刻的值是否相同(所有节点在同一时间的数据完全一致,结点越多,数据同步越耗时)
- 可用性(A):某一时刻负载突然增大时,集群整体是否还能响应客户端的请求(服务一直可用,而且是正常时间)
- 分区容错性(P):分区容忍性,即高可用性,即一个节点崩了,不影响其他节点(1000个节点,挂了几个,不影响服务,节点越多越好)
CAP理论就是说:在分布式存储系统中,最多只能实现上面的两点,而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须要实现的。所以我们必须在一致性和可用性之间进行权衡。
3、 分布式系统 CAP 原理常见面试题和注册中心选择- C、A 满足情况下,P 不能满足
数据同步(C)需要时间,服务一直可用(A)需要满足正常响应时间,若两者同时满足则要求不能有太多机器,即分区容错性(P)不能满足 - C、P 满足情况下,A 不能满足
数据同步(C)需要时间,分区容错性(P)使得机器数量众多,若两者同时满足则无法在正常时间内响应,可用性(A)不能满足 - A、P 满足情况下,C 不能满足
服务可用性(A)满足正常响应时间,分区容错性(P)使得机器数量众多,则数据无法及时同步到所有节点,一致性(C)不满足
- zookeeper:CP设计,保证了一致性和分区容错性,集群搭建的时候,某个节点失效,则会进行选举选出新的 leader,选举过程中不对外提供服务;如果集群中半数以上节点不可用,也无法对外提供服务。
- eureka:AP设计,无主从节点,一个节点挂了,自动切换其他节点,去中心化。
分布式系统中 P 肯定要满足,只能在 C、A 中二选一:
最好的选择是根据业务场景来选择架构:
如果要求一致性,则选择 zookeeper,如:银行
如果要求可用性,则选择 eureka,如:电商
参考:https://blog.csdn.net/zjcjava/article/details/78608892
5、 服务注册和发现之 Eureka Server 搭建(Eureka服务端搭建)使用 IDEA 搭建 Eureka 服务中心 Server 端并启动
官方文档:https://cloud.spring.io/spring-cloud-netflix/reference/html/
-
创建项目 eureka_server:
-
启动类上添加注解:@EnableEurekaServer
-
在 application.yml(也称 application.properties)中增加配置:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
#声明自己是个服务端
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
-
启动
-
地址栏输入http://localhost:8761/访问注册中心页面:
- 新建项目:product_service
- 写一个简单的商品模块
Product类:
package net.xdclass.product_service.domain;
import java.io.Serializable;
public class Product implements Serializable {
private int id;
private String name;
private int price;
private int store;
public Product() {
}
public Product(int id, String name, int price, int store) {
this.id = id;
this.name = name;
this.price = price;
this.store = store;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getStore() {
return store;
}
public void setStore(int store) {
this.store = store;
}
}
ProductService接口:
package net.xdclass.product_service.service;
import net.xdclass.product_service.domain.Product;
import java.util.List;
public interface ProductService {
List listProduct();
Product findById(int id);
}
ProductServiceImpl类:
package net.xdclass.product_service.service.impl;
import net.xdclass.product_service.domain.Product;
import net.xdclass.product_service.service.ProductService;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class ProductServiceImpl implements ProductService {
private static final Map daoMap = new HashMap<>();
static {
Product p1 = new Product(1, "Gin", 5613, 512);
Product p2 = new Product(2, "Vodka", 4851, 453);
Product p3 = new Product(3, "Sherry", 3244, 657);
Product p4 = new Product(4, "Rum", 4156, 234);
Product p5 = new Product(5, "Bourbon", 8934, 435);
Product p6 = new Product(6, "Vermouth", 453, 6523);
Product p7 = new Product(7, "Rye", 5343, 56);
Product p8 = new Product(8, "tequila", 2353, 3245);
daoMap.put(p1.getId(), p1);
daoMap.put(p2.getId(), p2);
daoMap.put(p3.getId(), p3);
daoMap.put(p4.getId(), p4);
daoMap.put(p5.getId(), p5);
daoMap.put(p6.getId(), p6);
daoMap.put(p7.getId(), p7);
daoMap.put(p8.getId(), p8);
}
@Override
public List listProduct() {
Collection products = daoMap.values();
List list = new ArrayList<>(products);
return list;
}
@Override
public Product findById(int id) {
return daoMap.get(id);
}
}
ProductController类:
package net.xdclass.product_service.controller;
import net.xdclass.product_service.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("api/v1/product")
public class ProductController {
@Autowired
private ProductService productService;
@RequestMapping("list")
public Object list(){
return productService.listProduct();
}
@RequestMapping("find")
public Object findById(@RequestParam("id") int id){
return productService.findById(id);
}
}
- 启动 product_service,测试以上两个功能是否可执行:
4. 在 application.yml(也称:application.properties)中添加配置:
server:
port: 8771
#指定注册中心地址
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
#指定服务的名称
spring:
application:
name: product-service
-
启动 eureka_server ,启动 product_service,访问http://localhost:8761/:
-
再启动一个 product_service:
再次启动 product_service,访问 http://localhost:8761/
问题一:一串红字
自我保护模式禁止关闭,默认是开启状态。
问题二:为什么只加一个注册中心地址,就可以注册



