微服务发布与调用
认识Eureka框架
Eureka提供基于REST的服务,在集群中主要用于服务管理。Eureka提供了基于Java语言的客户端组件,客户端组件实现了负载均衡的功能,为业务组件的集群部署创造了条件。使用该框架,可以将业务组件注册到Eureka容器中,进行集群部署。Eureka 提供的服务 调用功能,可以发布容器中的服务并进行调用。
Eureka架构
有两个服务器,服务器支持集群部署,每个服务器也可以作为对方服务器的客 户端进行相互注册与复制。图 3-1 的三个 Eureka 客户端,两个用于发布服务,其中一个用 于调用服务。不管服务器还是客户端,都可以部署多个实例,如此一来,就很容易构建高可用的服务集群。
服务器端
对于注册到服务器端的服务组件,Eureka 服务器并没有提供后台的存储,这些注册的 服务实例被保存在内存的注册中心,它们通过心跳来保持其最新状态,这些操作都可以在内 存中完成。客户端存在着相同的机制,同样在内存中保存了注册表信息,这样的机制提升了 Eureka 组件的性能,每次服务的请求都不必经过服务器端的注册中心。
服务提供者
作为 Eureka 客户端存在的服务提供者,主要进行以下工作:第一、向服务器注册服务; 第二、发送心跳给服务器;第三、向服务器端获取注册列表。当客户端注册到服务器时,它 将会提供一些关于它自己的信息给服务器端,例如自己的主机、端口、健康检测连接等。
服务调用者
对于发布到 Eureka 服务器的服务,使用调用者可对其进行服务查找与调用,服务调用 者也是作为客户端存在,但其职责主要是发现与调用服务。在实际情况中,有可能出现本身 既是服务提供者,也是服务调用者的情况,例如传统的企业应用三层架构中,服务层会调用 数据访问层的接口进行数据操作,它本身也会提供服务给控制层使用。
Eureka注册中心
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
启动类配置,加入如下注解
@SpringBootApplication
//加入了@EnableEurekaServer, 声明这是一个 Eureka 服务器
@EnableEurekaServer
public class FirstServer {
public static void main(String[] args) {
new SpringApplicationBuilder(FirstServer.class).run(args);
}
}
配置文件.yml
server:
port: 8761
启动抛出如下两个异常:
java.net.ConnectException: Connection refused: connect
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
由于在服务器启动时,服务器会把自己当作一个客户端,注册去 Eureka 服务器, 并且会到 Eureka 服务器抓取注册信息,它自己本身只是一个服务器,而不是服务的提供者 (客户端),因此可以修改 application.yml 文件,修改以下两个配置:
eureka:
client:
#声明是否将自己的信息注册到 Eureka 服务器,默认值为 true
registerWithEureka: false
#是否到 Eureka 服务器中抓取注册信息
fetchRegistry: false
Eureka服务提供者
引入依赖
<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>
配置文件配置.yml
spring:
application:
#注册引用名称
name: first-service-provider
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone:http://localhost:8761/eureka/
主启动类加入如下注解
@SpringBootApplication
//声明该应用是一个 Eureka 客户端。
@EnableEurekaClient
public class FirstServiceProvider {
public static void main(String[] args) {
new SpringApplicationBuilder(FirstServiceProvider.class).run(args);
}
}
启动程序后,方可在eureka服务管理页面看到注册的信息
Eureka服务调用者
服务被注册、发布到Eureka服务器后,需要有程序去发现它,并且进行调用。所以Eureka客户端可以当服务的注册者,也可以作为服务的调用方。由于同一个服务,可能会部署多个实例,调用过程中可能涉及负载均衡、服务器查找等问题。
引入依赖
<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>
配置文件.yml
server:
port: 9000
spring:
application:
name: first-service-invoker
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone:http://localhost:8761/eureka/
主启动类
@SpringBootApplication
//该注解使得服务调用者,有能力去 Eureka 中发现服务,需要注意的是@EnableEurekaClient注解已经包含了 @EnableDiscoveryClient 的功能
@EnableDiscoveryClient
public class FirstInvoker {
public static void main(String[] args) {
SpringApplication.run(FirstInvoker.class, args);
}
}
应用场景
@RestController
@Configuration
public class InvokerController {
@Bean
//@LoadBalanced 注解,这个 RestTemplate 实例就具有访 问分布式服务的能力
@LoadBalanced
public RestTemplate getRestTemplate() {
return newRestTemplate();
}
@RequestMapping(value = "/router", method= RequestMethod.GET, produces= MediaType.APPLICATION_JSON_VALUE)
public String router() {
RestTemplaterestTpl = getRestTemplate();
// 根据应用名称调用服务
String json = restTpl.getForObject( "http://first-service-provider/person/1", String.class);
return json;
}
}
以上为疯狂SpringCloud微服务架构实战学习笔记
感谢杨恩雄老师:https://my.oschina.net/JavaLaw