什么是服務(wù)注冊(cè)中心
服務(wù)注冊(cè)中心是服務(wù)實(shí)現(xiàn)服務(wù)化管理的核心組件,類似于目錄服務(wù)的作用,主要用來(lái)存儲(chǔ)服務(wù)信息,譬如提供者 url 串猴伶、路由信息等挽绩。服務(wù)注冊(cè)中心是 SOA 架構(gòu)中最基礎(chǔ)的設(shè)施之一。
服務(wù)注冊(cè)中心的作用
1稳其,服務(wù)的注冊(cè)
2扩氢,服務(wù)的發(fā)現(xiàn)
常見(jiàn)的注冊(cè)中心有哪些
1耕驰,Dubbo 的注冊(cè)中心 Zookeeper
2,Sringcloud 的注冊(cè)中心 Eureka
服務(wù)注冊(cè)中心解決了什么問(wèn)題
- 服務(wù)管理
- 服務(wù)的依賴關(guān)系管理
什么是 Eureka 注冊(cè)中心
Eureka 是 Netflix 開(kāi)發(fā)的服務(wù)發(fā)現(xiàn)組件录豺,本身是一個(gè)基于 REST 的服務(wù)朦肘。Spring Cloud將它集成在其子項(xiàng)目 spring-cloud-netflix 中,以實(shí)現(xiàn) Spring Cloud 的服務(wù)注冊(cè)于發(fā)現(xiàn)双饥,同時(shí)還提供了負(fù)載均衡厚骗、故障轉(zhuǎn)移等能力。
Eureka 注冊(cè)中心三種角色
1.Eureka Server
通過(guò) Register兢哭、Get领舰、Renew 等接口提供服務(wù)的注冊(cè)和發(fā)現(xiàn)。
2.Application Service (Service Provider)
服務(wù)提供方迟螺,把自身的服務(wù)實(shí)例注冊(cè)到 Eureka Server 中冲秽。
3.Application Client (Service Consumer)
服務(wù)調(diào)用方,通過(guò) Eureka Server 獲取服務(wù)列表矩父,消費(fèi)服務(wù)锉桑。
Eureka 單機(jī)服務(wù)端配置
添加啟動(dòng)器:Eureka Server啟動(dòng)類中添加@EnableEurekaServer注解
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
application文件配置
#當(dāng)前服務(wù)名稱
spring.application.name=MyEureka
#服務(wù)端口
server.port=8761
#是否將服務(wù)本身自己注冊(cè)到eureka
eureka.client.register-with-eureka=false
#是否從eureka服務(wù)中獲取獲取注冊(cè)信息
eureka.client.fetch-registry=false
啟動(dòng)啟動(dòng)類,訪問(wèn)本機(jī)IP+服務(wù)端口窍株,看到如下頁(yè)面民轴,表示服務(wù)已經(jīng)啟動(dòng)成功Eureka 服務(wù)器集群的搭建
啟動(dòng)器和啟動(dòng)類跟單機(jī)版一樣
application配置文件需要更改
集群服務(wù)器1的配置
spring.application.name=MyEureka
server.port=8761
#設(shè)置eureka實(shí)例名稱
eureka.instance.hostname=eureka1
#eureka集群中其他服務(wù)器的連接地址
eureka.client.serviceUrl.defaultZone=http://eureka2:8761/eureka/
集群服務(wù)器2的配置
spring.application.name=MyEureka
server.port=8761
#設(shè)置eureka實(shí)例名稱
eureka.instance.hostname=eureka2
#eureka集群中其他服務(wù)器的連接地址
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/
本次集群是通過(guò)多臺(tái)Linux虛擬機(jī)進(jìn)行架設(shè)
將項(xiàng)目打包為jar文件攻柠,在Linux中部署,部署方法后裸,通過(guò)java -jar xxx.jar 運(yùn)行jar文件即可瑰钮,如需要指定配置文件,
通過(guò)--spring.profiles.active={profile} 指定配置文件后綴即可微驶,
如果想后臺(tái)運(yùn)行浪谴,可以通過(guò)腳本文件運(yùn)行,腳本文件如下:
#!/bin/bash
cd `dirname $0`
CUR_SHELL_DIR=`pwd`
CUR_SHELL_NAME=`basename ${BASH_SOURCE}`
JAR_NAME="項(xiàng)目名稱(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
然后設(shè)置腳本文件執(zhí)行限權(quán): chmod 755 腳本文件名
然后通過(guò) 腳本文件名 start 啟動(dòng)服務(wù)因苹,腳本文件名 stop 停止服務(wù)
測(cè)試Eureka集群注冊(cè)中心
創(chuàng)建provider項(xiàng)目
項(xiàng)目創(chuàng)建:
application配置文件
#配置程序名稱凶杖,通過(guò)Eureka注冊(cè)時(shí),顯示的是此名稱
#配置應(yīng)用名稱款筑,通過(guò)Eureka注冊(cè)時(shí)官卡,顯示的是此名稱
spring.application.name=MyEureka.provider
#配置應(yīng)用端口
server.port=9090
#配置eureka集群的連接地址
eureka.client.serviceUrl.defaultZone=http://eureka2:8761/eureka/,http://eureka1:8761/eureka/
實(shí)體類
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;
}
}
啟動(dòng)類
類上使用@EnableEurekaClient注解,表示是Eureka客戶端醋虏,進(jìn)行Eureka注冊(cè)
@EnableEurekaClient
@SpringBootApplication
public class EurekaProviderApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class, args);
}
}
創(chuàng)建consumer項(xiàng)目
創(chuàng)建項(xiàng)目:
application配置文件
#配置應(yīng)用名稱,通過(guò)Eureka注冊(cè)時(shí)哮翘,顯示的是此名稱
spring.application.name=MyEureka.consumers
#配置應(yīng)用端口
server.port=8080
#eureka集群的連接地址
eureka.client.serviceUrl.defaultZone=http://eureka2:8761/eureka/,http://eureka1:8761/eureka/
實(shí)體類:
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)置對(duì)象ribbon 負(fù)載均衡器
public List<User> getUsers() {
//ServiceInstance 封裝了服務(wù)的基本信息颈嚼,如 IP,端口
ServiceInstance si = loadBalancerClient.choose("MyEureka.provider");//選擇調(diào)用的服務(wù)的名稱
//拼接訪問(wèn)服務(wù)的 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;
}
}
測(cè)試
運(yùn)行consumer和provider啟動(dòng)類饭寺。
然后訪問(wèn)集群中任意的web頁(yè)面阻课,可以看到剛剛編寫(xiě)的consumer和provider注冊(cè)成功
如圖艰匙,已經(jīng)得到provider注冊(cè)到Eureka注冊(cè)中心中的數(shù)據(jù)