服务治理:在传统rpc远程调用中,服务与服务依赖关系,管理比较复杂,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
服务注册与发现:在服务注册与发现中,有一个注册中心,当服务器启动的时候,会把当前自己服务器的信息比如服务地址通讯等以别名方式注册到注册中心上。另一方(服务消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地rpc调用远程。
服务提供者:指提供服务接口
服务消费者:指调用接口进行使用
Eureka由Eureka服务端和Eureka客户端两个组件组成,Eureka服务端用作服务注册中心。支持集群部署。Eureka客户端是一个java客户端,用来处理服务注册与发现。在应用启动时,Eureka客户端向服务端注册自己的服务信息,同时将服务端信息缓存到本地。客户端会和服务端周期性的进行心跳交互,以更新服务租约和服务信息。
自我保护机制:默认情况下EurekaClient定时向EurekaServer端发送心跳包。如果EurekaServer在一定的时间内没有收到EurekaClient发送心跳包,便会直接从服务注册列表中剔除该服务(默认90秒内)。但是在短时间丢失了大量的服务实例心跳,这时候EurekaServer会开启自我保护机制,不会去剔除该服务。
在自我保护机制,为什么Eureka不会剔除该服务呢?
为了防止EurekaClient是可以正常访问,但只是EurekaClient与EurekaServer网络访问不通。防止误剔除。(建议在本地环境禁止自我保护机制,在生产环境开启自我保护机制)
eureka:
server:
###测试时关闭自我保护机制,保证不可用服务及时踢出
enable-self-preservation: false
###剔除失效服务间隔
eviction-interval-timer-in-ms: 2000
搭建注册中心
pom文件中Maven依赖信息
<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.M7</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- SpringCloud eureka-server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <!-- 注意:这里必须要添加,否则各种依赖有问题 --> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/libs-milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
配置文件(application.yml)
###服务端口号
server:
port: 8100
eureka:
instance:
###注册中心ip地址
hostname: 127.0.0.1
client:
service-url:
###注册中心地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
###因为自己是注册中心,是否需要将自己注册给自己的注册中心(集群的时候是需要是为true)
register-with-eureka: false
###因为自己是注册中心,不需要去检索服务信息
fetch-registry: false
测试类
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer //表示开启EurekaServer服务,开启注册中心 public class AppEureka { public static void main(String[] args) { SpringApplication.run(AppEureka.class, args); } }
搭建完成!
注册服务提供者
pom文件中Maven依赖信息
<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.M7</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <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> <!-- 注意:这里必须要添加,否则各种依赖有问题 --> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/libs-milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
配置文件(application.yml)
###会员项目的端口号
server:
port: 8000
###服务别名(服务注册到注册中心名称)
spring:
application:
name: app-hclz-member
eureka:
client:
service-url:
###当前会员服务注册到eureka服务地址
defaultZone: http://localhost:8100/eureka
###需要将我的服务注册到eureka上
register-with-eureka: true
###需要检索服务
fetch-registry: true
主类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient //将当前服务注册到eureka上
public class AppMember {
public static void main(String[] args) {
SpringApplication.run(AppMember.class, args);
}
}
controller
@RestController public class MemberApiController { @RequestMapping("/getMember") public String getMember() { return "this is member,我是会员服务,springcloud2.0版本"; } }
启动注册中心后启动服务提供者
搭建服务提供者注册到Eureka成功!
注册服务消费者
pom文件中Maven依赖信息与服务提供者一致
配置文件(application.yml)
###订单服务的端口号
server:
port: 8001
###服务别名(服务注册到注册中心名称)
spring:
application:
name: app-hclz-order
eureka:
client:
service-url:
###当前会员服务注册到eureka服务地址
defaultZone: http://localhost:8100/eureka
###需要将我的服务注册到eureka上
register-with-eureka: true
###需要检索服务
fetch-registry: true
controller
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController public class OrderController { //RestTemplate是由SpringBoot Web组件提供,默认整合ribbon负载均衡器 //rest方式底层是采用httpclient技术 @Autowired private RestTemplate restTemplate; //订单服务调用会员服务 @RequestMapping("/getOrder") public String getOrder() { String url = "http://app-hclz-member/getMember"; String result = restTemplate.getForObject(url, String.class); System.out.println("订单服务调用会员服务result:"+result); return result; } }
主类
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.client.RestTemplate; @SpringBootApplication @EnableDiscoveryClient public class AppOrder { public static void main(String[] args) { SpringApplication.run(AppOrder.class, args); } @Bean //把RestTemplate注册到SpringBoot容器中,如果使用rest方式以别名方式进行调用,依赖ribbon负载均衡器@LoadBalanced @LoadBalanced //@LoadBalanced开启以别名方式去Eureka读取注册信息,然后本地实现rpc远程调用 RestTemplate restTemplate() { return new RestTemplate(); } }
启动注册中心接着启动服务提供者然后启动服务消费者
搭建服务消费者注册到Eureka成功!