Eureka服务注册中心
目录
1. Eureka基本介绍
Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。
SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。
Eureka包含两个组件:Eureka Server和Eureka Client。
Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。
在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。
2. Eureka环境构建
2.1 EurekaServer端
2.1.1 Maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RC2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
2.1.2 配置文件
server:
port: 9090 #服务注册中心端口号
spring:
application:
name: spring-cloud-eureka-server
eureka:
instance:
hostname: 127.0.0.1 #服务注册中心IP地址
client:
registerWithEureka: false #是否向服务注册中心注册自己
fetchRegistry: false #是否检索服务
serviceUrl: #服务注册中心的配置内容,指定服务注册中心的位置
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
2.1.3 启动类
package com.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @Author: JYC
* @Title: AppEurekaServer
* @Description: TODO
* @Date: 2022/4/21 18:46
*/
@SpringBootApplication
@EnableEurekaServer
public class AppEurekaServer {
public static void main(String[] args) {
SpringApplication.run(AppEurekaServer.class);
}
}
2.2 EurekaClient端
2.2.1 Maven
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RC2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
2.2.2 配置文件
server:
port: 8080
spring:
application:
name: demo-member #服务名称 在注册中心展示服务名称
eureka:
client:
service-url: # 服务注册中心地址
defaultZone: http://127.0.0.1:9090/eureka/
2.2.3 启动类
package com.demo.service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @Author: JYC
* @Title: com.demo.service.AppMember
* @Description: TODO
* @Date: 2022/4/21 13:59
*/
@SpringBootApplication
@EnableEurekaClient
public class AppMember {
public static void main(String[] args) {
SpringApplication.run(AppMember.class);
}
}
2.3 服务发现
2.3.1 Maven
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RC2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
2.3.2 配置文件
server:
port: 8070
spring:
application:
name: demo-order #服务名称 在注册中心展示服务名称
eureka:
client:
service-url: # 服务注册中心地址
defaultZone: http://127.0.0.1:9090/eureka/
2.3.3 启动类
package com.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @Author: JYC
* @Title: AppOrder
* @Description: TODO
* @Date: 2022/4/21 14:10
*/
@SpringBootApplication
@EnableDiscoveryClient
public class AppOrder {
public static void main(String[] args) {
SpringApplication.run(AppOrder.class);
}
}
2.2.4 接口
package com.demo.service;
import com.demo.utils.HttpClientUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Author: JYC
* @Title: OrderToMemberService
* @Description: TODO
* @Date: 2022/4/21 14:04
*/
@RestController
public class OrderToMemberService {
@Autowired
private DiscoveryClient discoveryClient;
/**
* 订单服务,调用 会员服务接口
*/
@RequestMapping("/orderToMember")
public String OrderToMember() {
// HttpClient 工具类 实现RPC远程调用
// String memberUrl = "http://192.168.66.1:8080/getMember";
/**
* 根据服务名称,从注册中心获取会员的接口地址
*/
List<ServiceInstance> instances = discoveryClient.getInstances("demo-member");
ServiceInstance serviceInstance = instances.get(0);
// 会员服务的ip和端口
String memberUrl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/" + "getMember";
return "订单服务调用会员服务:" + HttpClientUtils.doGet(memberUrl, null);
}
}
2.2.5 工具类
package com.demo.utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @Author: JYC
* @Title: OrderToMemberService
* @Description: TODO
* @Date: 2022/4/21 14:04
*/
public class HttpClientUtils {
private static final CloseableHttpClient httpClient;
public static final String CHARSET = "UTF-8";
private static final Log log = LogFactory.getLog(HttpClientUtils.class);
// 采用静态代码块,初始化超时时间配置,再根据配置生成默认httpClient对象
static {
RequestConfig config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build();
httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
}
public static String doGet(String url, Map<String, String> params) {
return doGet(url, params, CHARSET);
}
public static String doPost(String url, Map<String, String> params) throws IOException {
return doPost(url, params, CHARSET);
}
/**
* HTTP Get 获取内容
*
* @param url 请求的url地址 ?之前的地址
* @param params 请求的参数
* @param charset 编码格式
* @return 页面内容
*/
public static String doGet(String url, Map<String, String> params, String charset) {
try {
if (params != null && !params.isEmpty()) {
List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
for (Map.Entry<String, String> entry : params.entrySet()) {
String value = entry.getValue();
if (value != null) {
pairs.add(new BasicNameValuePair(entry.getKey(), value));
}
}
// 将请求参数和url进行拼接
url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
}
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
httpGet.abort();
throw new RuntimeException("HttpClient,error status code :" + statusCode);
}
HttpEntity entity = response.getEntity();
String result = null;
if (entity != null) {
result = EntityUtils.toString(entity, "utf-8");
}
EntityUtils.consume(entity);
response.close();
return result;
} catch (Exception e) {
log.error("请求服务器端出错:" + e);
return null;
}
}
/**
* HTTP Post 获取内容
*
* @param url 请求的url地址 ?之前的地址
* @param params 请求的参数
* @param charset 编码格式
* @return 页面内容
* @throws IOException
*/
public static String doPost(String url, Map<String, String> params, String charset)
throws IOException {
List<NameValuePair> pairs = null;
if (params != null && !params.isEmpty()) {
pairs = new ArrayList<NameValuePair>(params.size());
for (Map.Entry<String, String> entry : params.entrySet()) {
String value = entry.getValue();
if (value != null) {
pairs.add(new BasicNameValuePair(entry.getKey(), value));
}
}
}
HttpPost httpPost = new HttpPost(url);
if (pairs != null && pairs.size() > 0) {
httpPost.setEntity(new UrlEncodedFormEntity(pairs, CHARSET));
}
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
httpPost.abort();
throw new RuntimeException("HttpClient,error status code :" + statusCode);
}
HttpEntity entity = response.getEntity();
String result = null;
if (entity != null) {
result = EntityUtils.toString(entity, "utf-8");
}
EntityUtils.consume(entity);
return result;
} catch (ParseException e) {
log.error("请求服务器端出错:" + e);
return null;
} finally {
if (response != null)
response.close();
}
}
}
2.4 Eureka 常用配置解析
Eureka 常用配置解析(点击跳转)
3. 效果展示
3.1 启动EurekaServer端
浏览器访问:http://127.0.0.1:9090/
出现如下界面表示服务端启动成功
3.2 启动EurekaClient端
浏览器访问:http://127.0.0.1:9090/
在界面中能看到"DEMO-MEMBER"表示启动成功
3.3 启动服务发现
浏览器访问:http://127.0.0.1:9090/
在界面中能看到"DEMO-ORDER"表示启动成功
3.4 接口测试
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131273.html