关于Spring Cloud
资料参考:Spring Cloud官网
Spring Cloud为开发人员提供了工具,可以快速构建分布式系统中的一些常见模式(譬如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领袖选举(字面翻译)、分布式会话、集群状态)。协调分布式系统致力于统一工作,并且使用Spring Cloud的开发人员可以快速地实现这些模式的服务和应用程序。他们将会很好地工作在任何分布式环境下,包括开发人员自己的笔记本上,裸金属数据中心(字面翻译),以及像云计算这样的管理平台。
关于Eureka
Eureka是Spring Cloud提供的众多模块中的一个,它主要用于服务管理,对服务进行分布式和集群。Eureka提供了服务器端和客户端,服务端致力于服务列表的维护和后台管理,客户端分为提供者和调用者。实际上每一个客户端将自己注册到服务器端之后,其余的客户端就能检索发现对应的服务,所以提供者和调用者是针对调用关系来说的,实际上每一个客户端都可以同时作为提供者和调用者。如图的结构所示,我们这里创建一个Eureka服务器端,两个Eureka客户端(一个作为提供者,一个作为调用者),来演示具体的调用过程。
创建Eureka服务器端
使用MyEclipse新建一个简单java(JDK是1.8的)的maven项目eureka-server,参照开头给出的官网,我们这里选择Dalston SR5作为本次演示的版本。
进入Reference,查看版本文档,Ctrl+F搜索eureka,找到我们的服务器端。
然后按照指示说明,在我们eureka-server项目中的pom.xml文件中引入依赖,完整的引用如下所示:
<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.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
在src/main/java目录下新建com.init.springCloud包,创建启动文件ServerApp.class,添加Spring Boot的注解和Eureka服务器端的注解
package com.init.springCloud;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class ServerApp {
public static void main(String[] args) {
new SpringApplicationBuilder(ServerApp.class).web(true).run(args);
// 在最新的Greenwich.SR4版本下,web()的参数变成了WebApplicationType
}
}
之后在src/main/resources下创建application.yml(这里是配置的单机模式),标明服务器端使用的端口号为8761,Eureka客户端默认会将自己的服务注册到8761,同时也会去8761端口抓取服务列表;配置实例为本机(单机模式),因为是作为服务器端,这里就不要再注册自己的服务到服务器端,所以这里将默认的注册行为关闭,同时把抓取服务列表也关闭,最后配置默认访问空间(Eureka客户端需要注册服务的地址),完整配置如下:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
完成了上面的配置和代码编写,就可以启动我们的eureka-server了,运行ServerApp的main()方法,访问http://localhost:8761,在浏览器看到我们的后台管理页面,Eureka服务器端就搭建完成了
创建Eureka客户端的提供者
新建一个简单java的maven项目eureka-provider,依然是参照上面给出的官网,这里给出所有的相关代码和配置,在pom.xml中引入Eureka客户端的依赖,配置如下:
<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.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- lombok代码模板解决方案,没有使用lombok的可以把这个依赖删除 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies>
在src/main/java目录下新建com.init.springCloud包,创建启动类ProviderApp.class,引入Eureka客户端注解
package com.init.springCloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class, args);
}
}
新建class类Person,这里使用了lombok,未使用的读者可以去掉@Data注解,自行创建getter(),Setter()方法
package com.init.springCloud;
import lombok.Data;
@Data
public class Person {
private Integer id; //主键ID
private String name; //姓名
}
之后再创建一个Rest风格的控制器ProviderController,用于向调用者提供自己的服务,没有特殊的地方,直接贴代码:
package com.init.springCloud;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProviderController {
@RequestMapping(value = "/search/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Person searchPerson(@PathVariable Integer id){
Person person = new Person();
person.setId(id);
person.setName("Spirit");
return person;
}
}
之后在src/main/resources下创建application.yml,写明自己的服务名称和需要注册到那个Eureka服务器上
spring:
application:
name: eureka-provider
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
运行ProviderApp的main()方法,启动成功后访问http://localhost:8080/search/1,这里没有配置端口,就默认使用了8080端口,在浏览器端可以看到控制器返回的数据
再次访问http://localhost:8761,可以看到我们的服务提供者已经注册到Eureka服务器了
创建Eureka客户端的调用者
提供者已经创建完毕,为了验证我们是否可以调用来自提供者的服务,我们接着创建一个简单java的maven项目eureka-consumer,在pom.xml中加入依赖,由于都是作为Eureka客户端,所以eureka-sonsumer的依赖和eureka-provider的依赖相同,只不过调用者作为服务的请求一方,并不关心具体是怎么拿到服务的,而服务提供者有可能不止一个,意思是同一个服务可能做了集群,所以我们这里需要额外加入一个Ribbon的依赖,用作于负载均衡,让eureka-consumer自行适配需要使用的服务
<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.cloud</groupId>
<artifactId>spring-cloud-starter-config</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>
</dependencies>
在src/main/java目录下新建com.init.springCloud包,创建启动类ConsumerApp.class,引入Eureka客户端注解
package com.init.springCloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
}
继续创建一个普通类型的控制器类ConsumerController,按上面所说的,我们需要让eureka-consumer引用Spring RestTemplate作为一个负载均衡的客户端,值得注意的是:RestTemplate是Spring框架里面提供的,它可以自动配置去使用Ribbon。要创建一个负载均衡的RestTemplate,使用创建RestTemplate的Bean组件(@Bean)并使用@LoadBalanced限定符。
package com.init.springCloud;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
@Controller
@Configuration
public class ConsumerController {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
@GetMapping(value = "/router")
@ResponseBody
public String router(){
RestTemplate temp = getRestTemplate();
return temp.getForObject("http://eureka-provider/search/1", String.class);
}
}
URL地址需要使用虚拟主机名称,Ribbon客户端会创建完整的物理地址。
最后,在src/main/resources下创建application.yml,写明自己的服务名称和需要注册到那个Eureka服务器上,并配置属于自己的端口
server:
port: 8081
spring:
application:
name: eureka-consumer
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
运行ConsumerApp的main()方法,启动成功后访问http://localhost:8081/router,在浏览器端,我们可以看见eureka-consumer成功调用了eureka-provider的方法。
再次访问http://localhost:8761,我们可以看到eureka-server控制台上维护着两个Eureka客户端
最后,大家有什么不懂的或者其他需要交流的内容,也可以进入我的QQ讨论群一起讨论:654331206
Spring Cloud系列:
Spring Cloud服务管理框架Eureka简单示例(三)