什么是服務注冊中心
服務注冊中心是服務實現(xiàn)服務化管理的核心組件,類似于目錄服務的作用,主要用來存儲服務信息,譬如提供者 url 串、路由信息等。服務注冊中心是 SOA 架構中最基礎的設施之一。
服務注冊中心的作用
1,服務的注冊
2,服務的發(fā)現(xiàn)
常見的注冊中心有哪些
1,Dubbo 的注冊中心 Zookeeper
2,Sringcloud 的注冊中心 Eureka
服務注冊中心解決了什么問題
- 服務管理
- 服務的依賴關系管理
什么是 Eureka 注冊中心
Eureka 是 Netflix 開發(fā)的服務發(fā)現(xiàn)組件,本身是一個基于 REST 的服務。Spring Cloud將它集成在其子項目 spring-cloud-netflix 中,以實現(xiàn) Spring Cloud 的服務注冊于發(fā)現(xiàn),同時還提供了負載均衡、故障轉(zhuǎn)移等能力。
Eureka 注冊中心三種角色
1.Eureka Server
通過 Register、Get、Renew 等接口提供服務的注冊和發(fā)現(xiàn)。
2.Application Service (Service Provider)
服務提供方,把自身的服務實例注冊到 Eureka Server 中。
3.Application Client (Service Consumer)
服務調(diào)用方,通過 Eureka Server 獲取服務列表,消費服務。
Eureka 單機服務端配置
添加啟動器:Eureka Server
啟動類中添加@EnableEurekaServer注解
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
application文件配置
#當前服務名稱
spring.application.name=MyEureka
#服務端口
server.port=8761
#是否將服務本身自己注冊到eureka
eureka.client.register-with-eureka=false
#是否從eureka服務中獲取獲取注冊信息
eureka.client.fetch-registry=false
啟動啟動類,訪問本機IP+服務端口,看到如下頁面,表示服務已經(jīng)啟動成功
Eureka 服務器集群的搭建
啟動器和啟動類跟單機版一樣

application配置文件需要更改
集群服務器1的配置
spring.application.name=MyEureka
server.port=8761
#設置eureka實例名稱
eureka.instance.hostname=eureka1
#eureka集群中其他服務器的連接地址
eureka.client.serviceUrl.defaultZone=http://eureka2:8761/eureka/
集群服務器2的配置
spring.application.name=MyEureka
server.port=8761
#設置eureka實例名稱
eureka.instance.hostname=eureka2
#eureka集群中其他服務器的連接地址
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/
本次集群是通過多臺Linux虛擬機進行架設
將項目打包為jar文件,在Linux中部署,部署方法,通過java -jar xxx.jar 運行jar文件即可,如需要指定配置文件,
通過--spring.profiles.active={profile} 指定配置文件后綴即可,
如果想后臺運行,可以通過腳本文件運行,腳本文件如下:
#!/bin/bash
cd `dirname $0`
CUR_SHELL_DIR=`pwd`
CUR_SHELL_NAME=`basename ${BASH_SOURCE}`
JAR_NAME="項目名稱(jar包的全名含.jar后綴)"
JAR_PATH=$CUR_SHELL_DIR/$JAR_NAME
#JAVA_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:PermSize=128m"
JAVA_MEM_OPTS=""
SPRING_PROFILES_ACTIV="-Dspring.profiles.active=配置文件變量名稱"
#SPRING_PROFILES_ACTIV=""
LOG_DIR=$CUR_SHELL_DIR/logs
LOG_PATH=$LOG_DIR/${JAR_NAME%..log
echo_help()
{
echo -e "syntax: sh $CUR_SHELL_NAME start|stop"
}
if [ -z $1 ];then
echo_help
exit 1
fi
if [ ! -d "$LOG_DIR" ];then
mkdir "$LOG_DIR"
fi
if [ ! -f "$LOG_PATH" ];then
touch "$LOG_DIR"
fi
if [ "$1" == "start" ];then
# check server
PIDS=`ps --no-heading -C java -f --width 1000 | grep $JAR_NAME | awk '{print $2}'`
if [ -n "$PIDS" ]; then
echo -e "ERROR: The $JAR_NAME already started and the PID is ${PIDS}."
exit 1
fi
echo "Starting the $JAR_NAME..."
# start
nohup java $JAVA_MEM_OPTS -jar $SPRING_PROFILES_ACTIV $JAR_PATH >> $LOG_PATH 2>&1 &
COUNT=0
while [ $COUNT -lt 1 ]; do
sleep 1
COUNT=`ps --no-heading -C java -f --width 1000 | grep "$JAR_NAME" | awk '{print $2}' | wc -l`
if [ $COUNT -gt 0 ]; then
break
fi
done
PIDS=`ps --no-heading -C java -f --width 1000 | grep "$JAR_NAME" | awk '{print $2}'`
echo "${JAR_NAME} Started and the PID is ${PIDS}."
echo "You can check the log file in ${LOG_PATH} for details."
elif [ "$1" == "stop" ];then
PIDS=`ps --no-heading -C java -f --width 1000 | grep $JAR_NAME | awk '{print $2}'`
if [ -z "$PIDS" ]; then
echo "ERROR:The $JAR_NAME does not started!"
exit 1
fi
echo -e "Stopping the $JAR_NAME..."
for PID in $PIDS; do
kill $PID > /dev/null 2>&1
done
COUNT=0
while [ $COUNT -lt 1 ]; do
sleep 1
COUNT=1
for PID in $PIDS ; do
PID_EXIST=`ps --no-heading -p $PID`
if [ -n "$PID_EXIST" ]; then
COUNT=0
break
fi
done
done
echo -e "${JAR_NAME} Stopped and the PID is ${PIDS}."
else
echo_help
exit 1
fi
然后設置腳本文件執(zhí)行限權: chmod 755 腳本文件名
然后通過 腳本文件名 start 啟動服務,腳本文件名 stop 停止服務

測試Eureka集群注冊中心
創(chuàng)建provider項目
項目創(chuàng)建:

application配置文件
#配置程序名稱,通過Eureka注冊時,顯示的是此名稱
#配置應用名稱,通過Eureka注冊時,顯示的是此名稱
spring.application.name=MyEureka.provider
#配置應用端口
server.port=9090
#配置eureka集群的連接地址
eureka.client.serviceUrl.defaultZone=http://eureka2:8761/eureka/,http://eureka1:8761/eureka/
實體類
public class User {
private int id;
private String name;
private int age;
public User() {
}
public User(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
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 getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
controller
@RestController
public class UserController {
@RequestMapping("user")
public List<User> getUsers(){
List<User> list = new ArrayList();
list.add(new User(1,"張三",18));
list.add(new User(2,"李四",24));
list.add(new User(3,"王五",25));
return list;
}
}
啟動類
類上使用@EnableEurekaClient注解,表示是Eureka客戶端,進行Eureka注冊
@EnableEurekaClient
@SpringBootApplication
public class EurekaProviderApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class, args);
}
}
創(chuàng)建consumer項目
創(chuàng)建項目:

application配置文件
#配置應用名稱,通過Eureka注冊時,顯示的是此名稱
spring.application.name=MyEureka.consumers
#配置應用端口
server.port=8080
#eureka集群的連接地址
eureka.client.serviceUrl.defaultZone=http://eureka2:8761/eureka/,http://eureka1:8761/eureka/
實體類:
public class User {
private int id;
private String name;
private int age;
public User() {
}
public User(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
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 getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
service
@Service
public class UserService {
@Autowired
private LoadBalancerClient loadBalancerClient;//Spring的內(nèi)置對象ribbon 負載均衡器
public List<User> getUsers() {
//ServiceInstance 封裝了服務的基本信息,如 IP,端口
ServiceInstance si = loadBalancerClient.choose("MyEureka.provider");//選擇調(diào)用的服務的名稱
//拼接訪問服務的 URL
StringBuilder sb = new StringBuilder();
sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/user");
//springMVC RestTemplate
RestTemplate rt = new RestTemplate();
ParameterizedTypeReference<List<User>> parameterizedTypeReference = new ParameterizedTypeReference<List<User>>() {};
//ResponseEntity:封裝了返回值信息
ResponseEntity<List<User>> exchange = rt.exchange(sb.toString(), HttpMethod.GET, null, parameterizedTypeReference);
List<User> list = exchange.getBody();
return list;
}
}
controller
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("getuser")
public List<User> getUsers(){
List<User> users = userService.getUsers();
return users;
}
}
測試
運行consumer和provider啟動類。
然后訪問集群中任意的web頁面,可以看到剛剛編寫的consumer和provider注冊成功


如圖,已經(jīng)得到provider注冊到Eureka注冊中心中的數(shù)據(jù)