之前已经通过一系列博客完成了Dubbo相关知识和源码的学习,接下来我们学习一下Spring Cloud相关的知识。
Spring Cloud给我们提供了快速构建分布式系统的一系列工具,包括服务注册与发现、配置管理、断路器、路由、消息总线、全局锁、选举、分布式会话等等(可以通过官网http://projects.spring.io/spring-cloud/了解一些其提供的相关框架功能)。接下来我们通过Spring Cloud Netflix的Eureka模块来简单认识一下Spring Cloud的服务注册与发现功能。
一、注册中心
由于Spring Cloud是基于spring boot开发的,因此我们需要了解相关Spring boot的知识(其实很简单,内置容器或者外置容器,通过注解完成相关bean的注入)。
1、创建Maven工程
在pom.xml中引入eureka注册中心相关的jar
<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">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<!--选定spring cloud的版本-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxx</groupId>
<artifactId>TJWspringCloud-RegisterServer</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>TJWspringCloud-RegisterServer</name>
<dependencies>
<!--eureka注册中心相关的jar-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/test/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、eureka注册中心相关代码
eureka注册中心很简单,主要添加一个@EnableEurekaServer注解即可知道这个为eureka注册中心。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class ServerRegisterCenter {
public static void main(String[] args) {
SpringApplication.run(ServerRegisterCenter.class, args);
}
}
3、eureka注册中心相关配置
在工程的resource目录下添加application.propertie(或者application.yml)添加spring boot及eureka注册中心相关的配置。
#application name
spring.application.name=eureka-server
#tomcat's port
server.port=1001
#hostname
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
通过eureka.client.registerWithEureka:false和fetchRegistry:false来表明自己是一个eureka server.
通过访问http://localhost:1001即可看到注册中心相关页面。
二、服务提供者
服务提供者向注册中心进行服务注册时只是简单的注册一下自己的主机和端口、URL等一些简单信息(与Dubbo不一样,dubbo会将比较详细的接口信息注册到注册中心中),并且服务提供者会与注册中心维持一个心跳不断的进行保活,当超出心跳时间后注册中心会将服务提供者删除,并且eureka注册中心提供了服务下线的接口,服务提供者可以进行主动下线操作。
1、pom.xml中相关配置
只要引入eureka client相关的jar即可。
<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">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modelVersion>4.0.0</modelVersion>
<groupId>com.tianjunwei</groupId>
<artifactId>TJWspringCloud-provider</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>TJWspringCloud-provider</name>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/test/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
服务提供者代码,服务提供者并不需要向注册中心提供自己接口相关的信息,主要提供的就是主机、端口和URL等相关信息
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableEurekaClient
@RestController
public class ProviderApplication {
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return "hello spring cloud eureka";
}
@RequestMapping("/health")
@ResponseBody
public String health(){
return "I am health";
}
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
服务提供者的application.properties中需要配置注册中心的URL信息,这样服务提供者才能通过接口进行服务的注册、保活和下线等操作。
spring.application.name=computer-service
spring.cloud.client.hostname=127.0.0.1
server.port=3333
eureka.instance.hostname=127.0.0.1
#eureka注册中心URL信息
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
当启动服务提供者时会在eureka的注册中心中看到服务提供者相关的服务信息。
三、服务消费者
简单来说服务消费者与服务提供者类似都是向注册中心提供简单的服务信息进行服务注册,完成服务注册之后服务消费者和服务提供者都能获取到注册中心的服务列表,这样服务提供者和服务消费者都可以根据服务列表中的服务信息进行一系列的服务调用操作。
1、服务消费者
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
@RestController
public class ConsumerApplication {
@Autowired
RestTemplate restTemplate;
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return restTemplate.getForObject("http://COMPUTER-SERVICE/hello",String.class);
}
@RequestMapping("/hi")
@ResponseBody
public String hi(){
return "hi Spring cloud eureka";
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
服务消费者同样需要配置自身及注册中心相关地址即可
server.port=2001
spring.cloud.client.hostname=127.0.0.1
spring.application.name=computer-consumer
eureka.instance.hostname=127.0.0.1
#注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
启动之后就会在注册中心看到消费者的服务信息了
在浏览器中调用消费者的http://localhost:2001/hello即可获取到服务提供者的数据。
并且在Spring Cloud中服务消费者和服务提供者是相对的,我们也可以通过服务提供者COMPUTER-SERVICE的http://localhost:3333:/hi接口访问到服务消费者COMPUTE-CONSUMER的http://localhost:2001/hi提供的服务。
修改后的服务提供者代码如下
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
@RestController
public class ProviderApplication {
@Autowired
RestTemplate restTemplate;
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return "hello spring cloud eureka";
}
@RequestMapping("/health")
@ResponseBody
public String health(){
return "I am health";
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
@RequestMapping("/hi")
@ResponseBody
public String hi(){
return restTemplate.getForObject("http://COMPUTER-CONSUMER/hi",String.class);
}
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
访问结果如下: