大概在上个星期,基于spring boot 2 的第一个spring cloud稳定版本finchley发布了,本专题将基于finchley介绍spring cloud。当然,首先必须具备spring boot基础。
服务注册与服务发现
spring cloud主要用于快速构建分布式系统,而服务注册与服务发现是其实现分布式的核心基础,先来了解一下它的运行机制
- 注册中心启动:用于衔接各个服务与客户端。
- 服务启动:将服务接口的url注册到注册中心。
- 客户端启动:从注册中心获取服务url,存入本机缓存。
- 客户端请求服务:从本机缓存中获取服务url,直接请求。
公共pom.xml配置
三个项目的pom.xml都要做以下配置,以此表明这是一个spring cloud项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
注册中心
pom.xml追加配置:eureka-server就是注册中心,netflix是开发eureka的厂商。
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
bootstrap.yml配置:注意,spring cloud相关配置可以写在bootstrap.yml文件中,而application.yml文件主要做一些业务相关配置,如数据库连接等。这样便于管理,关于yml可以参考https://blog.csdn.net/wangb_java/article/details/80029104
server:
port: 8761
java代码:@EnableEurekaServer是自动配置注册中心,其他都是spring boot语法,启动项目。
@SpringBootApplication
@EnableEurekaServer
public class Eureka {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}
现在直接访问浏览器:http://localhost:8761/ 可以看到注册中心界面。注意启动时会报错:Connection refused: connect或Cannot execute request on any known server,说明一切正常,如果报其他错则配置失败。报错原因以后再讲。
服务端和客户端 pom.xml 追加配置
这里的artifactId是eureka-client,而上面注册中心是eureka-server,即对于注册中心来说,服务端和客户端都是client,pom.xml配置是一样的,它们都是注册中心的一个节点。具体是服务端还是客户端只是我们人为的区分,客户端可以调用服务端接口,服务端也可以调用客户端的接口,此时角色就互换了。
<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-client</artifactId>
</dependency>
</dependencies>
服务端
bootstrap.yml配置。
server:
port: 8081
spring:
application:
name: server
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
- spring.application.name:当前结点在注册中心的注册名字,其他结点就是通过这个名字来找到它。
- defaultZone:配置要连接到的注册中心地址,当上面注册中心启动后,默认会激活http://localhost:8761/eureka地址。
java代码:
@SpringBootApplication
@EnableEurekaClient //自动配置Eureka客户端
@RestController
public class Server {
public static void main(String[] args) {
SpringApplication.run(Server.class, args);
}
@GetMapping("/hello")
public String hello() {
return "hello world";
}
- 这里注解是@EnableEurekaClient,之前注册中心是@EnableEurekaServer
- 只有一个hello接口,准备给客户端调用
客户端
bootstrap.yml配置。
server:
port: 8080
spring:
application:
name: client
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
- 端口8080,name是client,其他都和服务端一样
java代码
@SpringBootApplication
@EnableEurekaClient
@RestController
public class Client {
public static void main(String[] args) {
SpringApplication.run(Client.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.build();
}
@Autowired
RestTemplate restTemplate;
@GetMapping("/")
public String html() {
return restTemplate.getForObject("http://SERVER//hello", String.class);
}
- restTemplate:相关内容参考https://blog.csdn.net/wangb_java/article/details/79832070
- @LoadBalanced:可以理解为将restTemplate对象配置成spring cloud的rest客户端,可以通过注册名访问注册中心的服务结点,使用如下。
- http://SERVER//hello:实际上就是http://localhost:8081//hello,但这里不再是url,而是直接通过注册名SERVER就可以找到8081的服务端了。这样做的作用就是,当服务端ip发生变化时,我们不需要去修改客户端代码。
hello world
- 此时,启动三个项目,访问http://localhost:8080/,页面上会显示hello world。具体实现流程参考本篇开头的那张图。只是这里只启动了一个服务。
- 再看一下http://localhost:8761/注册中心,此时可以看到三个结点的名字及相关状态。其中unknown就是注册中心,因为我前面没有给他起名。