Eureka是Netflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflix中,实现SpringCloud的服务发现功能。
为什么要使用Eureka,因为在一个完整的系统架构中,任何单点的服务都不能保证不会中断,因此我们需要服务发现机制,在某个节点中断后,其它的节点能够继续提供服务,从而保证整个系统是高可用的。
服务发现有两种模式:一种是客户端发现模式,一种是服务端发现模式。Erueka采用的是客户端发现模式。
feign:Feign是一个声明式的Web服务客户端,使用Feign可使得Web服务客户端的写入更加方便。 它具有可插拔注释支持,包括Feign注解和JAX-RS注解、Feign还支持可插拔编码器和解码器、Spring Cloud增加了对Spring MVC注释的支持,并HttpMessageConverters在Spring Web中使用了默认使用的相同方式。Spring Cloud集成了Ribbon和Eureka,在使用Feign时提供负载平衡的http客户端。
方式一:使用eureka实现服务治理
一、eureka-service 服务搭建
1、pom.xml
<?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.rainbow.eureka</groupId>
<artifactId>sikl-road-eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>sikl-road-eureka</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.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>Edgware.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
</project>
2、启动类加注解:@EnableEurekaServer
@EnableEurekaServer
@SpringBootApplication
public class EurekaDomeServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaDomeServiceApplication.class, args);
}
}
3、application.yml配置:
spring:
application:
name: eureka-service
server:
port: 1111 # 注册服务的端口号
eureka:
instance:
hostname: localhost # 指定主机名 (域名) 值=spring。profiles
server:
enable-self-preservation: false #关闭保护机制 可以将不可用的服务剔除
client:
register-with-eureka: false #不向注册中心注册资金
fetch-registry: false #关闭服务检索
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 将自己注册到peer2这个Eureka上面去
启动app 访问 http://localhost:1111/ 能显示下图服务就搭建成功了:
-------------------------------------------------------------------------------------------------------------------------------
二、provider-service搭建
1、pom.xml配置:
<?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.rainbow.eureka</groupId>
<artifactId>eureka-dome-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eureka-dome-service</name>
<description>service</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.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>Edgware.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
</project>
spring-cloud-starter-eureka 依赖就可以了
2、启动类加 @EnableEurekaClient 或者 @EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaDomeServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaDomeServiceApplication.class, args);
}
}
也可以使用@EnableEurekaClient 代替@EnableDiscoveryClient注解
3、application.yml 配置:
spring:
application:
name: test-service #服务名称
server:
port: 8083
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1111/eureka #注册中心
4、具体服务的代码和普通的controller相同:
@RestController
public class HelloController {
@RequestMapping("/hello")
public String index() {
return "hello word!";
}
}
5、运行app 访问http://localhost:1111/,能看到如下内容就算成功了:
---------------------------------------------------------------------------------------------------------------------------------
三、consumer-service 配置
方法一:
使用 RestTemplate 和 Ribbon相结合的方式,这里简单介绍一下Ribbon:
Ribbon是Netflix公司开源的一个负载均衡的项目,是一个客户端负载均衡器,运行在客户端上。它是一个经过了云端测试的IPC库,可以很好地控制HTTP和TCP客户端的一些行为。 Feign已经默认使用了Ribbon。
Ribbon能做负载均衡、容错、多协议(HTTP, TCP, UDP)支持异步和反应模型、缓存和批处理。
1、pom.xml配置:
<?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.rainbow.eureka</groupId>
<artifactId>eureka-dome-clean</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eureka-dome-clean</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.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>Edgware.SR1</spring-cloud.version>
</properties>
<dependency>
<groupId>io.sr</groupId>
<artifactId>sr-dh-biz-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
</project>
只需在pom中添加 spring-cloud-starter-eureka 和 spring-cloud-starter-ribbon 依赖
2、启动类添加: @EnableEurekaClient 和 负载均衡配置:
@EnableEurekaClient
@SpringBootApplication
public class EurekaDomeCleanApplication {
//开启客户端负载均衡
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(EurekaDomeCleanApplication.class, args);
}
3、application.ym 配置 eureka服务地址:
server:
port: 7777
eureka:
client:
register-with-eureka: false
serviceUrl:
defaultZone: http://localhost:1111/eureka
4、调用服务:
public String test() {
return service.getForObject("http://test-service:8080/hello", String.class);
}
注意test-service是你的服务名,不能是IP地址
方式二: 声明式服务调用: 使用eureka+feign框架
Spring Cloud Feign 是基于Netflix Feign 实现的,整理Spring Cloud Ribbon 与 Spring Cloud Hystrix,并且实现了声明式的Web服务客户端定义方式。
在spring cloud feign 的实现下,我们只需创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了在使用spring cloud ribbon时自行封装的开发量。简单的说方式二封装了方式一使开发变得更简单。
1、pom.xml配置:
<?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.dome</groupId>
<artifactId>eureka-clean</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.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>Dalston.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<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>
</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>
</project>
pom文件中要引入eureka依赖和feign依赖
2、在启动类中添加@EnableFeignClients 和 @EnableEurekaClient:
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class EurekaDomeCleanApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaDomeCleanApplication.class, args);
}
3、application.yml 配置:
server:
port: 7777
eureka:
client:
register-with-eureka: false
serviceUrl:
defaultZone: http://localhost:1111/eureka
4、创建接口:
@FeignClient("test-service")
public interface FeignService {
@RequestMapping("/hello")
String hello() ;
}
5、使用接口调用服务:
@Autowired
private FeignService fs;
public String test() {
return fs.hello();
}
这种方法开发是开发中最常用的方式,开发时provider会提供一个 provider-service-api 里面提供feign接口供consumer依赖使用
---------------------------------------------------------------------------------------------------------------------------------问题总结:
SpringCLoud中的“Discovery Service”有多种实现,比如:eureka, consul, zookeeper。
1,@EnableDiscoveryClient
注解是基于spring-cloud-commons
依赖,并且在classpath中实现;
2,@EnableEurekaClient
注解是基于spring-cloud-netflix
依赖,只能为eureka作用;
其实用更简单的话来说,就是如果选用的注册中心是eureka,那么就推荐@EnableEurekaClient,如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient。
开发时,consumer 启动类的位置最好和 provider启动类的位置相同,以免发生错误
使用eureka+feign方式时,建议使用三个模块: 服务提供者, 服务提供者提供的接口,服务消费者
feign为了方便开发人员使用所以提供的注解名城与springMVC的名称一致,只是名称一样所以使用时要多加小心不要犯错