Eureka 服务注册中心入门到掌握

一、 什么是服务注册中心

服务注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用,主要用来 存储服务信息,譬如提供者 url 串、路由信息等。服务注册中心是 SOA 架构中最基础的设 施之一。
1 服务注册中心的作用
1,服务的注册 2,服务的发现
举例:QQ群里面的群成员就是一个服务的注册;群成员发消息就是服务的发现.
2 常见的注册中心有哪些
1,Dubbo 的注册中心 Zookeeper
2,Sringcloud 的注册中心 Eureka
3 服务注册中心解决了什么问题
1.服务管理
2.服务的依赖关系管理
4 什么是 Eureka 注册中心
Eureka 是 Netflix 开发的服务发现组件,本身是一个基于 REST 的服务。Spring Cloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 Spring Cloud 的服务注册于发现,同时 还提供了负载均衡、故障转移等能力。
5 Eureka 注册中心三种角色
5.1EurekaServer
通过 Register、Get、Renew 等接口提供服务的注册和发现。
5.2ApplicationService(ServiceProvider)
服务提供方 把自身的服务实例注册到 Eureka Server 中
5.3ApplicationClient(ServiceConsumer)
服务调用方 通过 EurekaServer 获取服务列表,消费服务。

二、 Eureka 入门案例

1 创建项目
在这里插入图片描述
2 修改 pom 文件添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjsxt</groupId>
    <artifactId>springcloud-eureka-server-ha</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springcloud-eureka-server-ha</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
             </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3 修改启动类

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
	public static void main(String[] args) {
		SpringApplication.run(EurekaApplication.class, args);
	}
}

4 修改 application.properties 全局配置文件

spring.application.name=eureka-server 
server.port=8761
#是否将自己注册到 Eureka-Server 中,默认的为 true
eureka.client.registerWithEureka=false
#是否冲 Eureka-Server 中获取服务注册信息,默认为 true
eureka.client.fetchRegistry=false 

5 通过浏览器访问 Eureka-Server 服务管理平台
在这里插入图片描述

三、 搭建高可用 Eureka 注册中心(Eureka 集群)

1 创建项目
在这里插入图片描述
2 配置文件

#设置 eureka 实例名称,与配置文件的变量为主 
eureka.instance.hostname=eureka2
#设置服务注册中心地址,指向另一个注册中心 
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/

在搭建 Eureka 集群时,需要添加多个配置文件,并且使用 SpringBoot 的多环境配置方 式。集群中需要多少节点就添加多少个配置文件。
3 在配置文件中配置集群节点
3.1eureka1

#设置 eureka 实例名称,与配置文件的变量为主 
eureka.instance.hostname=eureka1
#设置服务注册中心地址,指向另一个注册中心 
eureka.client.serviceUrl.defaultZone=http://eureka2:8761/eureka/

3.2eureka2

#设置 eureka 实例名称,与配置文件的变量为主 
eureka.instance.hostname=eureka2
#设置服务注册中心地址,指向另一个注册中心 
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/

4 添加 logback 日志配置文件
5 Eureka 集群部署
部署环境:需要安装 jdk1.8,正确配置环境变量。 注意:需要关闭 linux 的防火墙,或者是开放 8761 端口
5.1将项目打包
Maveninstall
5.2上传实例
在/usr/local/创建一个 eureka 的目录 将项目的 jar 包拷贝到/usr/local/eureka
6 编写一个启动脚本文件

cd `dirname $0`
 
CUR_SHELL_DIR=`pwd`
CUR_SHELL_NAME=`basename ${BASH_SOURCE}`
 
JAR_NAME="项目名称"
JAR_PATH=$CUR_SHELL_DIR/$JAR_NAME
 
#JAVA_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:PermSize=128m"
JAVA_MEM_OPTS=""
 
SPRING_PROFILES_ACTIV="eureka1"
#SPRING_PROFILES_ACTIV="-Dspring.profiles.active=配置文件变量名称"
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

6.1设置启动脚本的运行权限
Chmod-R755server.sh
7 修改 linux 的 host 文件
Vim /etc/hosts
192.168.70.134 eureka1
192.168.70.135 eureka2
8 启动 eureka 注册中心
./server.shstart 启动
./server.shstop 停止
9 通过浏览器访问注册中心的管理页面
在这里插入图片描述

四、 在高可用的 Eureka 注册中心中构建 provider 服务

1 创建项目
在这里插入图片描述
2 修改 pom 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjsxt</groupId>
    <artifactId>springcloud-eureka-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springcloud-eureka-provider</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3 修改启动类

@EnableEurekaClient
@SpringBootApplication
public class EurekaApplication {
	public static void main(String[] args) {
		SpringApplication.run(EurekaApplication.class, args);
	}
}

4 修改 provider 的配置文件

spring.application.name=eureka-provider
server.port=9090

#设置服务注册中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/

5 修改 windows 的 host 文件
路径:C:\Windows\System32\drivers\etc
192.168.70.134 eureka1
192.168.70.135 eureka2
6 编写服务接口
6.1创建接口

@RestController
public class UserController {

    @RequestMapping("/user")
    public List<User> getUsers() {
        List<User> list = new ArrayList<>();
        list.add(new User(1, "zhangsan", 20));
        list.add(new User(2, "lisi", 22));
        list.add(new User(3, "wangwu", 20));
        return list;
    }
}

6.2创建 pojo

public class User {

	private int userid;
	private String username;
	private int userage;

	public int getUserid() {
		return userid;
	}

	public void setUserid(int userid) {
		this.userid = userid;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public int getUserage() {
		return userage;
	}

	public void setUserage(int userage) {
		this.userage = userage;
	}

	public User(int userid, String username, int userage) {
		super();
		this.userid = userid;
		this.username = username;
		this.userage = userage;
	}

	public User() {
		super();
		// TODO Auto-generated constructor stub
	}

}

五、 在高可用的 Eureka 注册中心中构建 consumer 服务
1 创建项目
在这里插入图片描述
服务的消费者与提供者都需要再 Eureka 注册中心注册。
2 Consumer 的配置文件

spring.application.name=eureka-provider
server.port=9091
#设置服务注册中心地址,指向另一个注册中心 
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/

3 在 Service 中完成服务的调用

@Service
public class UserService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;//ribbon负载均衡器

    public List<User> getUsers() {
        //选择调用的服务的名称
        //ServiceInstance 封装了服务的基本信息,如 IP,端口
        ServiceInstance si = this.loadBalancerClient.choose("eureka-provider");
        //拼接访问服务的URL
        StringBuffer sb = new StringBuffer();
        //http://localhost:9090/user
        sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/user");


        //springMVC RestTemplate
        RestTemplate rt = new RestTemplate();

        ParameterizedTypeReference<List<User>> type = new ParameterizedTypeReference<List<User>>() {
        };

        //ResponseEntity:封装了返回值信息
        ResponseEntity<List<User>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type);
        List<User> list = response.getBody();
        return list;
    }
}

4 Controller

@RestController public class UserController {
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/consumer")
    public List<User> getUsers() {
        return this.userService.getUsers();
    }
}

六、 Eureka 注册中心架构原理

1 Eureka 架构图
在这里插入图片描述
Register(服务注册):把自己的 IP 和端口注册给 Eureka。 Renew(服务续约):发送心跳包,每 30 秒发送一次。告诉 Eureka 自己还活着。 Cancel(服务下线):当 provider 关闭时会向 Eureka 发送消息,把自己从服务列表中删除。防 止 consumer 调用到不存在的服务。 GetRegistry(获取服务注册列表):获取其他服务列表。 Replicate(集群中数据同步):eureka 集群中的数据复制与同步。 MakeRemoteCall(远程调用):完成服务的远程调用。

七、 基于分布式 CAP 定理,分析注册中心两大主流框架:Eureka 与 Zookeeper 的区别

1 什么是 CAP 原则
CAP 原则又称 CAP 定理,指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。 CAP 由 Eric Brewer 在 2000 年 PODC 会议上提出。该猜想在提出两年后被证明成 立,成为我们熟知的 CAP 定理
在这里插入图片描述
在这里插入图片描述
2 Zookeeper 与 Eureka 的区别
在这里插入图片描述

八、 Eureka 优雅停服

1 在什么条件下,Eureka 会启动自我保护?
在这里插入图片描述
2 为什么要启动自我保护
在这里插入图片描述
3 如何关闭自我保护
修改 EurekaServer 配置文件

#关闭自我保护:true 为开启自我保护,false 为关闭自我保护 
eureka.server.enableSelfPreservation=false 
#清理间隔(单位:毫秒,默认是 60*1000) 
eureka.server.eviction.interval-timer-in-ms=60000

4 如何优雅停服
4.1不需要再 EurekaServer 中配置关闭自我保护
4.2需要再服务中添加 actuator.jar 包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.bjsxt</groupId>
	<artifactId>springcloud-eureka-provider</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>springcloud-eureka-provider</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.13.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR5</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka-server</artifactId>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

4.3修改配置文件

#启用 shutdown endpoints.shutdown.
enabled=true 
#禁用密码验证 
endpoints.shutdown.sensitive=false

4.4发送一个关闭服务的 URL 请求

public class HttpClientUtil {

	public static String doGet(String url, Map<String, String> param) {

		// 创建Httpclient对象
		CloseableHttpClient httpclient = HttpClients.createDefault();

		String resultString = "";
		CloseableHttpResponse response = null;
		try {
			// 创建uri
			URIBuilder builder = new URIBuilder(url);
			if (param != null) {
				for (String key : param.keySet()) {
					builder.addParameter(key, param.get(key));
				}
			}
			URI uri = builder.build();

			// 创建http GET请求
			HttpGet httpGet = new HttpGet(uri);

			// 执行请求
			response = httpclient.execute(httpGet);
			// 判断返回状态是否为200
			if (response.getStatusLine().getStatusCode() == 200) {
				resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (response != null) {
					response.close();
				}
				httpclient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return resultString;
	}

	public static String doGet(String url) {
		return doGet(url, null);
	}

	public static String doPost(String url, Map<String, String> param) {
		// 创建Httpclient对象
		CloseableHttpClient httpClient = HttpClients.createDefault();
		CloseableHttpResponse response = null;
		String resultString = "";
		try {
			// 创建Http Post请求
			HttpPost httpPost = new HttpPost(url);
			// 创建参数列表
			if (param != null) {
				List<NameValuePair> paramList = new ArrayList<>();
				for (String key : param.keySet()) {
					paramList.add(new BasicNameValuePair(key, param.get(key)));
				}
				// 模拟表单
				UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList,"utf-8");
				httpPost.setEntity(entity);
			}
			// 执行http请求
			response = httpClient.execute(httpPost);
			resultString = EntityUtils.toString(response.getEntity(), "utf-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				response.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return resultString;
	}

	public static String doPost(String url) {
		return doPost(url, null);
	}
	
	public static String doPostJson(String url, String json) {
		// 创建Httpclient对象
		CloseableHttpClient httpClient = HttpClients.createDefault();
		CloseableHttpResponse response = null;
		String resultString = "";
		try {
			// 创建Http Post请求
			HttpPost httpPost = new HttpPost(url);
			// 创建请求内容
			StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
			httpPost.setEntity(entity);
			// 执行http请求
			response = httpClient.execute(httpPost);
			resultString = EntityUtils.toString(response.getEntity(), "utf-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				response.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return resultString;
	}
	
	public static void main(String[] args) {
		String url ="http://127.0.0.1:9090/shutdown";
		//该url必须要使用dopost方式来发送
		HttpClientUtil.doPost(url);
	}
}

九、 如何加强 Eureka 注册中心的安全认证

1 在 EurekaServer 中添加 security 包

<dependency>
 <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId> 
</dependency>

2 修改 EurekaServer 配置文件

#开启 http basic 的安全认证
security.basic.enabled=true 
security.user.name=user 
security.user.password=123456

3 修改访问集群节点的 url

eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka2:8761/eureka/

4 修改微服务的配置文件添加访问注册中心的用户名与密码

spring.application.name=eureka-provider 
server.port=9090
#设置服务注册中心地址,指向另一个注册中心 
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
#启用shutdown 
endpoints.shutdown.enabled=true 
#禁用密码验证 
endpoints.shutdown.sensitive=false
发布了43 篇原创文章 · 获赞 72 · 访问量 6393

猜你喜欢

转载自blog.csdn.net/qq_43107323/article/details/104494056