服务治理 SpringCloudEureka——单片搭建

Posted Ethan_LiYan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了服务治理 SpringCloudEureka——单片搭建相关的知识,希望对你有一定的参考价值。

3章 服务治理 Spring Cloud Eureka

2.1 框架简介

Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件中的一部分,它基于Netflix Eureka做了二次封装,主要负责完成微服务架构中的服务治理功能

2.2 服务治理

服务治理可以说是微服务架构中,最为核心和基础的模块,主要围绕着服务注册于服务发现机制”来实现各个微服务实例的自动化注册与发现。包括:

2.2.1注册中心

①在服务治理框架中,通常都会构建一个注册中心每个服务单元向注册中心注册自己的服务,注册中心就会维护类似下面的一个服务清单

②注册中心会以心跳的方式去检测清单中的服务是否可用,若不可用需要从服务清单中剔出,以达到排出故障服务的效果。

2.2.2服务发现

①服务间的调用不再通过指定具体的实例地址来实现,而是通过服务名发起请求调用实现;

②实际考虑框架性能等因素,不会采用每次都向服务中心获取服务的方式,并且不同的应用场景在缓存和服务剔除等机制上也会有一些不同的实现策略。

2.3 Netfix Eureka

Spring Cloud Eureka 使用 Netflix Eureka 实现服务的注册与发现,他提供了用Java编写的服务端和客户端

2.3.1 Eureka服务端

Eureka服务端作用:服务注册中心

②允许在分片故障期间继续提供服务的发现和注册,当故障分片恢复后,集群中的其他分片会把它们的状态再次同步回来;

③不同可用区域的服务注册中心通过异步模式互相复制各自的状态,这意味着任意给定的时间点,每个实例关于所有服务的状态是有细微差别的。

2.3.2 Eurek客户端

Eureka客户端作用:服务的注册与发现

②客户端通过注解和参数的配置方式,嵌入在客户端应用程序的代码中,并向注册中心注册自身提供的服务,并周期性地发送心跳来更新他的服务租约

③同时,它也能从服务端查询当前注册的服务信息,并把它们缓存到本地并周期性的刷新服务状态


2.4 演示

2.4.1 搭建服务注册中心

1.创建maven工程,名称eureka-service,引入eureka-service依赖

<?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.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.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>
		<spring-cloud.version>Finchley.M8</spring-cloud.version>
		<spring-cloud-starter-eureka.version>1.4.3.RELEASE</spring-cloud-starter-eureka.version>
	</properties>
	
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-server</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-eureka</artifactId>
			<version>$spring-cloud-starter-eureka.version</version>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>$spring-cloud.version</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

</project>

2.通过@EnableEurekaServer注册启动一个服务注册中心,供给其他应用进行对话

package com.example.eurekaservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
 * 
 * <p>Title: EurekaServiceApplication</p>  
 * @author  Liyan  
 * @date    2018年3月21日 下午4:44:19
 * 通过@EnableEurekaServer注解启动一个注册中心,提供给其他应用对话
 */
@EnableEurekaServer
@SpringBootApplication
public class EurekaServiceApplication 

	public static void main(String[] args) 
		SpringApplication.run(EurekaServiceApplication.class, args);
	

3.编写application.properties文件,禁止注册中心注册自己

server.port=1111

#在默认设置下,eureka注册中心会将自己作为客户端来尝试注册自己,所以需要禁用======

eureka.instance.hostname=localhost

#不向注册中心注册自己

eureka.client.register-with-eureka=false

#注册中心的职责是维护服务实例,所以不需要去检索服务

eureka.client.fetch-registry=false

eureka.client.serviceUrl.defaultZone=http://$eureka.instance.hostname:$server.port/eureka/

4.启动,访问http://localhost:1111

 

2.4.2 注册服务提供者

1.修改hello-service项目,引入Spring Cloud Eureka模块的依赖

<?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.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.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>
		<spring-cloud.version>Finchley.M8</spring-cloud.version>
		<spring-cloud-starter-eureka.version>1.4.3.RELEASE</spring-cloud-starter-eureka.version>
	</properties>
	
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-server</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-eureka</artifactId>
			<version>$spring-cloud-starter-eureka.version</version>
		</dependency>
		
		<dependency>
		    <groupId>com.google.guava</groupId>
		    <artifactId>guava</artifactId>
		</dependency>	
		
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>$spring-cloud.version</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

</project>

2.修改/hello接口,注入DiscoverClient对象

package com.example.demo.web;

import java.util.List;
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.RequestMethod;
import org.springframework.web.bind.annotation.RestController;


/**
 * 编写一个测试类
 * <p>Title: HelloController</p>  
 * @author  Liyan  
 * @date    2018年3月19日 下午7:00:20
 */
@RestController
public class HelloController 
	
	@Autowired
	private DiscoveryClient discoveryClient;
	
	@RequestMapping(value = "/hello", method = RequestMethod.GET)
	public String index() 
	        
	        List<String> services = discoveryClient.getServices();
			System.out.println("discoveryClient.getServices().size() = " + services.size());  
	        for( String s :  services)  
	            System.out.println("services " + s);  
	            List<ServiceInstance> serviceInstances =  discoveryClient.getInstances(s);  
	            for(ServiceInstance si : serviceInstances)  
	                System.out.println("    services:" + s + ":getHost()=" + si.getHost());  
	                System.out.println("    services:" + s + ":getPort()=" + si.getPort());  
	                System.out.println("    services:" + s + ":getServiceId()=" + si.getServiceId());  
	                System.out.println("    services:" + s + ":getUri()=" + si.getUri());  
	                System.out.println("    services:" + s + ":getMetadata()=" + si.getMetadata());  
	              
	              
	          
	          
	        List<ServiceInstance> list = discoveryClient.getInstances("STORES");  
	        System.out.println(list.size());  
	        if (list != null && list.size() > 0 )   
	            System.out.println( list.get(0).getUri()  );  
	          
	        return null;  
	
	

3.在启动类上添加@EnableDiscoverClient注解,激活EurekaDiscoverClient实现

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
 * 模拟向注册中心发布自己
 * <p>Title: DemoApplication</p>  
 * @author  Liyan  
 * @date    2018年3月23日 上午10:37:03
 */
@EnableDiscoveryClient
@SpringBootApplication
public class DemoApplication 

	public static void main(String[] args) 
		SpringApplication.run(DemoApplication.class, args);
	

补充: @EnableDiscoveryClient注解和@EnableEurekaClient的简单区别

stackoverflow上的解释:

    There are multiple implementations of "Discovery Service" (eureka, consul, zookeeper). @EnableDiscoveryClient lives in spring-cloud-commons and picks the implementation on the classpath.  @EnableEurekaClient lives in spring-cloud-netflix and only works for eureka. If eureka is on your classpath, they are effectively the same.

简单解释:

@EnableEurekaClient的源码使用了@EnableDiscoveryClient注解,所以@EnableDiscoveryClient的使用范围更广eureka, consul, zookeeper),而@EnableEurekaClient仅适用于注册中心为Eureka的场景。

4.编写application.properties文件,指定服务名称及注册中心地址

#为当前服务命名

spring.application.name=hello-service

#指定注册中心地址

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

5.先启动注册中心eureka-service,再启动改造后的服务hello-service

 ①在hello-service控制台,看到如下信息,表示服务注册成功

 

②在eureka-service控制台,看到如下信息,表示名字为hello-service的服务被注册成功

 

访问注册中心http://localhost:1111,可以看到服务被注册成功

 

④访问应用http://localhost:8080/hello,看到控制台输出如下信息

services hello-service

    services:hello-service:getHost()=vian

    services:hello-service:getPort()=8080

    services:hello-service:getServiceId()=HELLO-SERVICE

    services:hello-service:getUri()=http://vian:8080



以上是关于服务治理 SpringCloudEureka——单片搭建的主要内容,如果未能解决你的问题,请参考以下文章

服务治理SpringCloudEureka—— 高可用注册中心

服务治理SpringCloudEureka—— 高可用注册中心

服务治理SpringCloudEureka—— 服务发现与消费

服务治理SpringCloudEureka—— 服务发现与消费

服务治理SpringCloudEureka——Eureka详解

服务治理SpringCloudEureka——Eureka详解