What is a Service registry
A service registry is a core component for service registration and management. Similar to a directory service, it is mainly used to store service information, such as service provider URL string and routing information. A service registry is one of the most fundamental infrastructures in an SOA architecture.
1. The role of the service registry
1. Registration of services
2 Service discovery
2. Common registry
1 Dubo registry Zookeeper
2 SpringCloud的Eureka
3. What problems do service registries solve
1. Service management
2. Service dependency management
4. What is the Eureka Registry
Eureka is a Service discovery component developed by Netflix. It is itself a REST-based service, and SpringCloud integrates it into its sub-project to realize SpringCloud’s service registration and discovery, as well as provide load balancing and registration
4.1 Three roles in the Eureka Registry
-
Eureka Server
Registers and discovers services through interfaces such as Register, Get, and Renew.
-
Application Service (Service Provider)
Service Provider
Register your service instance with Eureka Server
-
Application Client (Service Consumer)
Service caller
Obtain the service list from Eureka Server and consume the service
2. Introduction to Eureka
1. Create projects
1.1 Adding a Dependency
<?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>1.5.13. RELEASE</version>
<relativePath /> <! -- lookup parent from repository -->
</parent>
<groupId>com.luyi</groupId>
<artifactId>springcloud-eureka-server</artifactId>
<version>0.0.1 - the SNAPSHOT</version>
<name>springcloud-eureka-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<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>
Copy the code
1.2 Modifying the Startup Class
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); }}Copy the code
1.3 Modifying the Global Configuration File
Server. port=8761 # do you want to register with eureka-server? Defaults to true eureka. Client. RegisterWithEureka = false # whether from eureka - service information in the server, the default is true eureka. Client. FetchRegistry = falseCopy the code
1.4 Accessing the Eureka-Server Service Management Platform using a Browser
3. Build Eureka cluster
1. Create projects
1.1 Creating a Project
springcloud-eureka-server-ha
1.2 Modifying the Configuration File
When setting up a Eureka cluster, multiple configuration files need to be added, and the multi-environment configuration method of SpringBoot is used to add as many configuration files as needed in the cluster
1.3 Configuring cluster Nodes in the Configuration file
Eureka1
Port =8761 # set eureka instance name, Eureka.instance. hostname=eureka1 Point to another registry eureka. Client. ServiceUrl. DefaultZone = http://eureka2:8761/eureka/Copy the code
Eureka2
Port =8761 # set eureka instance name, Eureka.instance. hostname=eureka2 Point to another registry eureka. Client. ServiceUrl. DefaultZone = http://eureka1:8761/eureka/Copy the code
1.4 Adding the LogBack Log Configuration File
<?xml version="1.0" encoding="UTF-8" ? >
<configuration>
<! Do not use relative path in LogBack configuration -->
<property name="LOG_HOME" value="${catalina.base}/logs/" />
<! -- Console output -->
<appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
<! -- Log output code -->
<layout class="ch.qos.logback.classic.PatternLayout">
<! Format output: %d indicates the date, %thread indicates the thread name, %-5level indicates the level of 5 characters from the left. % MSG indicates the log message, %n indicates the newline character.
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
</appender>
<! Generate log files per day -->
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<! -- Log file output file name -->
<FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<! Format output: %d indicates the date, %thread indicates the thread name, %-5level indicates the level of 5 characters from the left. % MSG indicates the log message, %n indicates the newline character.
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
<! -- Maximum size of log file -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<! -- Log output level -->
<root level="DEBUG">
<appender-ref ref="Stdout" />
<appender-ref ref="RollingFile" />
</root>
<! -- Log asynchronous to database -->
<! - < appender name = "DB" class = "ch. Qos. Logback. Classic. DB. DBAppender" > asynchronous to the database log < connectionSource Class = "ch. Qos. Logback. Core. The DriverManagerConnectionSource" < > connection pool 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 > < / a dataSource > </connectionSource> </appender> -->
</configuration>
Copy the code
1.5 Eureka Cluster Deployment
Deployment environment: JDK1.8
-
Package projects
-
Upload the JAR package to the /usr/local/eureka folder
1.6 Writing startup Scripts
#! /bin/bashCD 'dirname $0' CUR_SHELL_DIR= 'PWD' CUR_SHELL_NAME= 'basename ${BASH_SOURCE}' JAR_NAME=" Project 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= Profile variable name"#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 fiCopy the code
Add permissions
chmod -R 755 server.sh
1.7 Modifying the hosts file on the Linux OS
vi /etc/hosts
192.168.234.130 eureka1
192.168.234.131 eureka2
Copy the code
1.8 Start the Eureka registry
Sh start # Start./server.sh stop # StopCopy the code
4. Set up the Provider service in the highly available Eureka registry
1. Create projects
springcloud-eureka-provider
1.1 Adding a Dependency
<?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>1.5.13. RELEASE</version>
<relativePath /> <! -- lookup parent from repository -->
</parent>
<groupId>com.luyi</groupId>
<artifactId>springcloud-eureka-provider</artifactId>
<version>0.0.1 - the SNAPSHOT</version>
<name>springcloud-eureka-provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<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>
Copy the code
1.2 Modifying the Startup Class
// Represents the client of Eureka
@EnableEurekaClient
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); }}Copy the code
1.3 Modifying the Provider Configuration File
Name =eureka-provider server.port=9090 To all the registry for registration eureka. Client. ServiceUrl. DefaultZone = http://eureka1:8761/eureka/, http://eureka2:8761/eureka/Copy the code
1.4 Modifying the Host file in Windows
C:\Windows\System32\drivers\etc
192.168.234.130 eureka1 192.168.234.131 eureka2
1.5 Writing service Interfaces
@RestController
public class UserController {
@RequestMapping("/user")
public List<User> getUsers(a){
List<User> users = new ArrayList<>();
users.add(new User(1."zhangsan".20));
users.add(new User(2."lisi".22));
users.add(new User(3."wangwu".30));
returnusers; }}Copy the code
1.6 Creating Entities
/** * Author: LuYi * Date: 2019/11/6 12:30 * Description: Description */
public class User {
private Integer userid;
private String username;
private Integer userage;
public User(a) {}public User(Integer userid, String username, Integer userage) {
this.userid = userid;
this.username = username;
this.userage = userage;
}
public Integer getUserid(a) {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getUsername(a) {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getUserage(a) {
return userage;
}
public void setUserage(Integer userage) {
this.userage = userage; }}Copy the code
5. Set up Consumer services in the highly available Eureka registry
Both consumers and producers of services need to register with the Eureka registry
1. Create projects
1.1 Consumer profile
Name =eureka-consumer server.port=9091 To all the registry for registration eureka. Client. ServiceUrl. DefaultZone = http://eureka1:8761/eureka/, http://eureka2:8761/eureka/Copy the code
1.2 Complete Service Invocation in Service
@Service
public class UserService {
@Autowired
private LoadBalancerClient loadBalancerClient; //ribbon: load balancer
public List<User> getUsers(a){
// Select the name of the service to invoke
//ServiceInstance: encapsulates basic service information, such as the IP address and port number
ServiceInstance si = loadBalancerClient.choose("eureka-provider");
// Concatenate the URL to access the service
StringBuffer sb = new StringBuffer();
//http://localhost:9090/user
sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/user");
//SpringMVC RestTemplate
RestTemplate restTemplate = new RestTemplate();
ParameterizedTypeReference<List<User>> type = new ParameterizedTypeReference<List<User>>() {
};
//ResponseEntity: encapsulates the return value information
ResponseEntity<List<User>> entity = restTemplate.exchange(sb.toString(), HttpMethod.GET, null, type);
returnentity.getBody(); }}Copy the code
1.3 create a Controller
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/consumer")
public List<User> getUsers(a){
returnuserService.getUsers(); }}Copy the code
6. Architecture principle of Eureka Registry
1. Eureka architecture diagram
- Register: Register your IP address and port number with Eureka
- Renew: Send heartbeat packets every 30 seconds to tell Eureka that they are alive
- Cancel: When the provider is closed, it sends a message to Eureka to remove itself from the list of services. Prevents a Consumer from invoking a service that doesn’t exist
- Get Registry: Get a list of other services
- Replicate (Data synchronization in a Cluster) : Data replication and synchronization in a Eureka cluster
- Make Remote Call: Complete the service Remote Call
7. Based on the distributed CAP theorem, this paper analyzes the differences between the two mainstream frameworks of registry: Eureka and Zookeeper
1. What are the CAP principles
The CAP principle, also known as the CAP theorem, refers to Consistency, Availability and Partition tolerance in distributed systems.
CAP was proposed by Eric Brewer at PODC 2000. The conjecture proved true two years later and became known as the CAP theorem
2. Differences between Zookeeper and Eureka
8. Eureka’s elegant stop service
1. Under what circumstances does Eureka turn on self-protection
1.1 Self-protection conditions
Generally, after Eureka is registered, the microserver sends heartbeat packets every 30 seconds, and deletes services that do not send heartbeat packets in the 90s periodically.
1.2 There are two conditions in which The Eureka Server cannot receive the heartbeat of the microservice
-
Microservices themselves
-
The reason for the network between microservices and Eureka
If a microservice fault occurs, a large number of heartbeat packets cannot be received, but only some faults occur. However, a network fault causes a large number of heartbeat packets cannot be received.
Considering this difference, Eureka sets a threshold. If a large number of heartbeat packets are not received within a short period of time, it will be judged as a network fault. In this way, Eureka will not delete the service whose heartbeat has expired
-
So what’s the threshold
Determine if it is below 85% within 15 minutes
Eureka Server determines whether 85% of heartbeat failures occur within 15 minutes
This algorithm is called Eureka Server’s self-protection mode.
2. Why protect yourself
- Because it is better to keep ** good data and ** bad data than to delete all data, if you enter self-protection mode because of network failure, when the fault is repaired, it will automatically exit self-protection mode
- The load balancing policy of microservice automatically removes dead microservice nodes
3. How do I turn off self-protection
Example Modify the Eureka Server configuration file
Eureka.server. enable-self-preservation=false eureka.server.enable-self-preservation=false Ms, default is 60*1000) Eureka. server.eviction- interval-timer-in-MS =60000Copy the code
4. 4. Smart Laundry peg
4.1 You do not need to disable self-protection in Eureka Server
4.2 Adding the skeleton.jar package to services
4.3 Modifying the Configuration File
# start shutdown endpoints. Shutdown. Enabled = true # disabled password authentication endpoints. The shutdown. The sensitive = falseCopy the code
4.4 Send a URL request to disable the service
public class HttpClientUtil {
public static String doGet(String url, Map<String, String> param) {
// Create an Httpclient object
CloseableHttpClient httpclient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
try {
/ / create a uri
URIBuilder builder = new URIBuilder(url);
if(param ! =null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// Create an HTTP GET request
HttpGet httpGet = new HttpGet(uri);
// Execute the request
response = httpclient.execute(httpGet);
// Check whether the return status is 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) {
// Create an Httpclient object
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// Create an Http Post request
HttpPost httpPost = new HttpPost(url);
// Create a parameter list
if(param ! =null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// Simulate the form
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList,"utf-8");
httpPost.setEntity(entity);
}
// Execute the HTTP request
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 blocke.printStackTrace(); }}return resultString;
}
public static String doPost(String url) {
return doPost(url, null);
}
public static String doPostJson(String url, String json) {
// Create an Httpclient object
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// Create an Http Post request
HttpPost httpPost = new HttpPost(url);
// Create the requested content
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// Execute the HTTP request
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 blocke.printStackTrace(); }}return resultString;
}
public static void main(String[] args) {
String url ="http://127.0.0.1:9090/shutdown";
// This URL must be sent in doPost modeHttpClientUtil.doPost(url); }}Copy the code
How to strengthen Eureka registration center security certification
1. Add the security package to EurekaServer
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Copy the code
2. Modify the Eureka Server configuration file
Security.basic. enabled=true security.user.name=user security.user.password=123456Copy the code
3. Change the url for accessing the cluster node
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka2:8761/eureka/
Copy the code
4. Modify the configuration file to change the user name and password for accessing the registry
Name =eureka-provider server.port=9090 Register with all registries eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/ # start shutdown endpoints. Shutdown. Enabled = true # disabled password authentication endpoints. The shutdown. The sensitive = falseCopy the code