一、什么是服务注册中心

服务注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用,主要用来存储服务信息,譬如提供者url串、路由信息等。服务注册中心是SOA架构中最基础的设施之一。

1服务注册中心的作用
1,服务的注册
2,服务的发现

2常见的注册中心有哪些
1,Dubbo 的注册中心Zookeeper
2,Springcloud的注册中心Eureka

3服务注册中心解决了什么问题

1.服务管理
2.服务的依赖关系管理
4什么是Eureka注册中心
Eureka是Netflix开发的服务发现组件,本身是一个基于REST的服务。Spring Cloud将它集成在其子项目spring-cloud-netflix中,以实现Spring Cloud的服务注册于发现,同时还提供了负载均衡、故障转移等能力。

5Eureka注册中心三种角色
5.1Eureka Server
通过Register、Get、Renew等接口提供服务的注册和发现。
5.2Application Service (Service Provider)
服务提供方
把自身的服务实例注册到Eureka Server中
5.3Application Client (Service Consumer)
服务调用方
通过Eureka Server 获取服务列表,消费服务。

二、Eureka入门案例

1.创建项目

注册中心 consul 下载 注册中心是什么_spring


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</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>springcloud-eureka-server</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>

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服务管理平台

注册中心 consul 下载 注册中心是什么_配置文件_02

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

1.创建项目

注册中心 consul 下载 注册中心是什么_配置文件_03


2.配置文件

#设置eureka实例名称,与配置文件的变量为主
eureka.instance.hostname=eureka2

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

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

3.在配置文件中配置集群节点
3.1eureka1

spring.application.name=eureka-server
server.port=8761

#设置eureka实例名称,与配置文件的变量为主
eureka.instance.hostname=eureka1

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

3.2eureka2

spring.application.name=eureka-server
server.port=8761

#设置eureka实例名称,与配置文件的变量为主
eureka.instance.hostname=eureka2

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

4.添加logback日志配置文件

注册中心 consul 下载 注册中心是什么_注册中心 consul 下载_04


5.Eureka集群部署

部署环境:需要安装jdk1.8,正确配置环境变量。

注意:需要关闭linux的防火墙,或者是开放8761端口

5.1将项目打包
Maven install

5.2上传实例
在/usr/local/创建一个eureka的目录
将项目的jar包拷贝到/usr/local/eureka

6.编写一个启动脚本文件

#!/bin/bash
 
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="-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

6.1设置启动脚本的运行权限
Chmod -R 755 server.sh

7.修改 linux的host文件
Vim /etc/hosts
192.168.70.134 eureka1
192.168.70.135 eureka2

8.启动eureka注册中心
./server.sh start 启动
./server.sh stop 停止

9.通过浏览器访问注册中心的管理页面

注册中心 consul 下载 注册中心是什么_ci_05

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

1.创建项目

注册中心 consul 下载 注册中心是什么_注册中心 consul 下载_06


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>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</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.创建项目

注册中心 consul 下载 注册中心是什么_配置文件_07

服务的消费者与提供者都需要再Eureka注册中心注册。
2.Consumer的配置文件

spring.application.name=eureka-consumer
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 {
    
    	@Autowired
    	private UserService userService;
    	
    	@RequestMapping("/consumer")
    	public List<User> getUsers(){
    		return this.userService.getUsers();
    	}
    }

六、Eureka注册中心架构原理

1.Eureka架构图

注册中心 consul 下载 注册中心是什么_配置文件_08


Register(服务注册):把自己的IP和端口注册给Eureka。

Renew(服务续约):发送心跳包,每30秒发送一次。告诉Eureka自己还活着。

Cancel(服务下线):当provider关闭时会向Eureka发送消息,把自己从服务列表中删除。防止consumer调用到不存在的服务。

Get Registry(获取服务注册列表):获取其他服务列表。

Replicate(集群中数据同步):eureka集群中的数据复制与同步。

Make Remote Call(远程调用):完成服务的远程调用。

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

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

分布式系统CAP定理

分布式系统CAP定理

C 数据一致性(Consistency)

也叫做数据原子性,系统在执行某项操作后仍然处于一致的状态。在分布式系统中,更新操作执行成功后所有的用户都应该读到最新的值,这样的系统被认为是具有强一致性的。等同于所有节点访问同一份最新的数据副本。

A 服务可用性(Availablity)

每一个操作总是能够在一定的时间内返回结果,这里需要注意的是"一定时间内"和"返回结果"。一定时间内指的是,在可以容忍的范围内返回结果,结果可以是成功或者是失败。

P 分区容错性(Partition-torlerance)

在网络分区的情况下,被分隔的节点仍能正常对外提供服务(分布式集群,数据被分布存储在不同的服务器上,无论什么情况,服务器都能正常被访问)

定律:任何分布式系统只可同时满足二点,没法三者兼顾。

CA,放弃P

如果想避免分区容错性问题的发生,一种做法是将所有的数据(与事务相关的)都放在一台机器上。虽然无法100%保证系统不会出错,单不会碰到由分区带来的负面效果。当然这个选择会严重的影响系统的扩展性。

CP,放弃A

相对于放弃"分区容错性"来说,其反面就是放弃可用性。一旦遇到分区容错故障,那么受到影响的服务需要等待一定时间,因此在等待时间内系统无法对外提供服务。

AP,放弃C

这里所说的放弃一致性,并不是完全放弃数据一致性,而是放弃数据的强一致性,而保留数据的最终一致性。以网络购物为例,对只剩下一件库存的商品,如果同时接受了两个订单,那么较晚的订单将被告知商品告罄。

2.Zookeeper与Eureka的区别

对比项

Zookeeper

Zookeeper

CAP

CP

AP

Dubbo集成

已支持

-

Spring Cloud集成

已支持

已支持

kv服务

支持

-

ZK支持数据存储,eureka不支持

使用接口(多语言能力)

提供客户端

http多语言

ZK的跨语言支持比较弱

watch支持

支持

支持

什么是Watch支持?就是客户单监听服务端的变化情况。zk通过订阅监听来实现eureka通过轮询的方式来实现

集群监控

_

metrics

metrics,运维者可以收集并报警这些度量信息达到监控目的

八、Eureka优雅停服

1.在什么条件下,Eureka会启动自我保护?

什么是自我保护模式
1,自我保护的条件
一般情况下,微服务在Eureka上注册后,会每30秒发送心跳包,Eureka通过心跳来判断服务时候健康,同时会定期删除超过90秒没有发送心跳服务。
2,有两种情况会导致Eureka Server收不到微服务的心跳
a.是微服务自身的原因
b.是微服务与Eureka之间的网络故障
通常(微服务的自身的故障关闭)只会导致个别服务出现故障,一般不会出现大面积故障,而(网络故障)通常会导致Eureka Server在短时间内无法收到大批心跳。
考虑到这个区别,Eureka设置了一个阀值,当判断挂掉的服务的数量超过阀值时,Eureka Server认为很大程度上出现了网络故障,将不再删除心跳过期的服务。
3,那么这个阀值是多少呢?
15分钟之内是否低于85%;
Eureka Server在运行期间,会统计心跳失败的比例在15分钟内是否低于85%
这种算法叫做Eureka Server的自我保护模式。

2.为什么要启动自我保护

为什么要自我保护
1,因为同时保留"好数据"与"坏数据"总比丢掉任何数据要更好,当网络故障恢复后,这个Eureka节点会退出"自我保护模式"。
2,Eureka还有客户端缓存功能(也就是微服务的缓存功能)。即便Eureka集群中所有节点都宕机失效,微服务的Provider和Consumer
都能正常通信。
3,微服务的负载均衡策略会自动剔除死亡的微服务节点。

3.如何关闭自我保护
修改Eureka Server配置文件

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

4.如何优雅停服
4.1不需要再Eureka Server中配置关闭自我保护
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.在Eureka Server中添加security包

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

2.修改Eureka Server配置文件

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

3.修改访问集群节点的url

eureka.client.serviceUrl.defaultZone=http://user:123456@eureka2: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