学习主题:Eureka
学习目标:
对应视频:
http://www.itbaizhan.cn/course/id/85.html
对应文档:
无
对应作业
1. 编写Eureka入门案例
(1) @EnableEurekaServer注解的作用是什么?
表示此项目是一个注册中心
2. 创建集群版的Eureka注册中心
(1) 创建一个Maven的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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>springcloud-eureka-server-ha</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(2) 修改POM文件,添加Eureka Server启动器。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
(3) 修改POM文件,添加Spring Boot的Web启动器。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
(4) 修改全局配置文件,添加注册中心配置。
spring.application.name=eureka-server
server.port=8761
eureka.instance.hostname=eureka1
(5) 修改全局配置文件,添加其他配置中心地址。
eureka.client.service-url.defaultZone=http://eureka2:8761/eureka/
(6) 添加Logback配置文件。
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="${catalina.base}/logs/" />
<!-- 控制台输出 -->
<appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出编码 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="DEBUG">
<appender-ref ref="Stdout" />
<appender-ref ref="RollingFile" />
</root>
<!--日志异步到数据库 -->
<!-- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
日志异步到数据库
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
连接池
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
<user>root</user>
<password>root</password>
</dataSource>
</connectionSource>
</appender> -->
</configuration>
3. Eureka集群部署
(1) 项目打包命令是什么?
Maven install
(2) 启动项目是如何加载不同的配置文件?
Java -jar xxx.jar --spring.profiles.active={profile}
(3) 如何修改Linux的Host文件?
注册中心的ip 映射名称
4. 创建provider服务
(1) @EnableEurekaClient注解的作用是什么?
表示它可以将服务注册到eureka中
5. 注册服务并测试接口
(1) 启动Provider。
(2) 在注册中心管理页面中,查看是否含有Provider服务。
(3) 启动浏览器,访问Provider服务做接口测试。
分享/讲解/扩展思考
点名提问从第一节课到最后一节课分别学到了什么,直到同学们把所有的知识点都说出来并且保证无误。
第238次(Eureka)
学习主题:Eureka
学习目标:
对应视频:
http://www.itbaizhan.cn/course/id/85.html
对应文档:
无
对应作业
6. 创建consumer服务
(1) 创建一个Maven的jar项目。
(2) 修改POM文件,添加Eureka启动器。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
(3) 修改POM文件,添加Spring Boot的Web启动器。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
(4) 修改全局配置文件,添加注册中心集群配置。
spring.application.name=eureka-consumer
server.port=9091
#设置服务注册中心地址,指向另一个注册中心
eureka.client.service-url.defaultZone=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/
(5) 在Service中通过LoadBalancerClient完成对服务的调用。
package com.bjsxt.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.bjsxt.pojo.User;
@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;
}
}
(6) 创建Controller,在Controller中注入Service对象。
@RestController
public class userController {
@Autowired
private UserService userService;
@RequestMapping("/consumer")
public List<User> usecontrolelr() {
return userService.getUsers();
}
7. 在consumer中调用provider服务
(1) 启动Consumer服务。
@EnableEurekaClient
@SpringBootApplication
public class SpringBootStarter {
public static void main(String[] args) {
SpringApplication.run(SpringBootStarter.class, args);
}
}
(2) 测试Consumer服务,查看调用Provider所返回的数据。
8. Eureka架构图原理
(1) 请描述Eureka架构原理。
9. 什么是CAP定理
(1) 什么是CAP原则?
CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性),Avilability(可用性),Partition tolerance(分区容错性) ,三者不可兼得
(2) C、A、P分别表示什么?
(3) CA、CP、AP分别表示什么含义?
10. ZooKeeper与Eureka的区别
(1) Zookeeper与Eureka有哪些区别?
11. Eureka的服务自我保护
(1) 什么是自我保护模式?
(2) 为什么要启动自我保护?
12. 关闭Eureka的服务自我保护
(1) 如何关闭自我保护?
13. 服务的优雅停服
(1) 如何实现优雅停服?
需要在服务中添加actuator.jar包
<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>
修改配置文件
#启用 shutdown
endpoints.shutdown.enabled=true
#禁用密码验证
endpoints.shutdown.sensitive=false
发送一个关闭服务的请求
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);
}
(2) 访问优雅停服的URI是什么?
Shutdown
14. 开启Eureka注册中心的安全认证
(1) 实现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@eur
eka2:8761/eureka/
(2) 如果开启安全认证,注册中心在集群环境下各个节点访问时,如何传递用户名与密码?
eureka.client.serviceUrl.defaultZone=http://user:123456@eur
eka2:8761/eureka/
分享/讲解/扩展思考
点名提问从第一节课到最后一节课分别学到了什么,直到同学们把所有的知识点都说出来并且保证无误。