建设电子商务网站步骤,php网站开发个人职责,企业概况的模板范文,公司销售管理系统服务注册与服务发现
Eureka的架构
Eureka客户端#xff1a;使用了EnableEurekaClient注解的应用服务#xff0c;如订单服务等#xff0c;甚至Eureka本身也是一个客户端 Eureka服务端#xff1a;使用了EnableEurekaServer注解的应用服务#xff0c;该服务提供了注册表以及…服务注册与服务发现
Eureka的架构
Eureka客户端使用了EnableEurekaClient注解的应用服务如订单服务等甚至Eureka本身也是一个客户端 Eureka服务端使用了EnableEurekaServer注解的应用服务该服务提供了注册表以及对服务节点的操作 服务提供者服务启动后可以向注册中心发起register请求将服务信息注册进去 服务消费者服务启动后可以从注册中心拉取服务信息并根据所得的服务信息调用服务 他们之间的关系为 Eureka-server你可以当作他是一个单独的服务而跟它对接的都是Eureka-client而Eureka-client中则包含了服务消费者和服务提供者等角色。例如订单服务中包含一个消费者A商品服务中包含一个提供者B现在消费者A想查询该订单对应的商品信息那就是查询提供者B的服务那么首先A和B都必须先把自己作为一个eureka客户端然后B将自己的服务信息发送到eureka的服务端中A再从eureka服务端中拉取B的服务信息地址然后发起请求。
服务端
所需依赖
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-netflix-eureka-server/artifactId
/dependency启动服务时需要添加两个注解
EnableEurekaServer
SpringBootApplication客户端
所需依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId
/dependency
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-netflix-eureka-client/artifactId
/dependency启动服务需要配置
EnableEurekaClient
SpringBootApplication关系
1、服务提供者、服务消费者、服务发现组件三者之间的关系大致如下: 1各个微服务在启动时时将自己的网络地址等信息注册到服务发现组件上(eureka,zookeeper,Consul,spring cloud alibaba的nacos),服务发现组件会存储这些信息。 2服务消费者会从服务发现组件查询服务提供者的网络地址然后将服务地址列表缓存到本地然后根据服务名负载均衡调用服务提供者的接口。 3各个微服务与服务发现组件使用一定的机制来维持心跳服务发现组件若发现有服务没有提供心跳那么服务发现组件会将该服务剔除。 4微服务网络地址发生变更(例如实例增减或者IP端口发生变化等)会重新注册到服务发现组件上使用这种方式可以避免因网络变化导致服务之间的通讯停止服务消费者也无须人工的修改网络地址。
Eureka简介
Eureka是Netflix开发的服务发现框架本身是一个基于REST的服务主要用于定位运行在AWS域中的中间层服务以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中以实现SpringCloud的服务发现功能。 1.Eureka包含两个组件Eureka Server和Eureka Client。 Eureka Server提供服务注册服务各个节点启动后会在Eureka Server中进行注册这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息服务节点的信息可以在界面中直观的看到。 Eureka Client是一个java客户端用于简化与Eureka Server的交互客户端同时也就是一个内置的、使用轮询负载算法的负载均衡器。 2.在应用启动后Eureka Client会向Eureka Server发送心跳,默认周期为30秒如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。 3.Eureka Server之间通过复制的方式完成数据的同步Eureka还提供了客户端缓存机制即使所有的Eureka Server都挂掉客户端依然可以利用缓存中的信息消费其他服务的API。综上Eureka通过心跳检查、客户端缓存等机制确保了系统的高可用性、灵活性和可伸缩性。
三、Eureka一些特性及配置过程时需要注意的问题 1.Eureka能够保证AP即当Eureka中的某个节点挂掉后剩余的节点继续仍然可以提供服务的发现与注册服务。而Eureka的客户端在向某个Eureka或者发现了当前的Eureka不可用时会自动切换到其他的节点也就是说Eureka的节点是平等的只要有一台Eureka服务器在就能保证服务的可以继续被使用。 2.Eureka的自我保护机制我们在注册服务时如发生断网的情况Eureka不能接收到当前服务的任何心跳请求Eureka会在默认的90s后将该服务进行强制剔除这样就能保证到网络故障时虽然失去了部分节点但不会像zookeeper那样会使整个注册服务瘫痪。当网络稳定时新的实例会同步到其他节点中。 3.相关配置问题 服务端的配置如下不注册自身
security:basic:enabled: trueuser:name: userpassword: password123
eureka:client:register-with-eureka: falsefetch-registry: falseservice-url:defaultZone: http://user:password123localhost:8761/eureka引入依赖
!-- eureka-server--
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-eureka-server/artifactIdversion1.2.3.RELEASE/version
/dependency!--eureka-client--
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-eureka/artifactIdversion1.2.3.RELEASE/version
/dependencyEureka客户端应用服务注册流程
1、应用集成eureka客户端依赖配置eureka相关信息 2、当应用启动完成后应用会自动向eureka-server服务发请求将自身的示例信息注册到eureka-server 3、会启动心跳进程和服务状态检测时间心跳每隔30s一次应用服务状态发生变更也会想eureka-server服务进行服务重新注册 4、当应用服务进行关闭时会调用shutdown方法进行服务下线的操作当服务因断电/网络问题/意外停机无法正确的下线服务时这时心跳就会起到相对应的作用如果eureka-server服务发现应用超过三次90s没有心跳那么就会将服务进行保护/下线
源码分析
源码分析 应用在服务启动时自动注册的实现配置类EurekaClientAutoConfiguration里面向IOC容器内注册了EurekaAutoServiceRegistration.class对象
Bean
ConditionalOnBean(AutoServiceRegistrationProperties.class)
ConditionalOnProperty(value spring.cloud.service-registry.auto-registration.enabled, matchIfMissing true)
public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry registry,EurekaRegistration registration) {return new EurekaAutoServiceRegistration(context, registry, registration);
}EurekaAutoServiceRegistration.class实现了SmartLifecycle.class SmartLifecycle.class这个类是在应用启动后自动调用start()
Override
public void start() {// 端口配置if (this.port.get() ! 0) {if (this.registration.getNonSecurePort() 0) {this.registration.setNonSecurePort(this.port.get());}if (this.registration.getSecurePort() 0 this.registration.isSecure()) {this.registration.setSecurePort(this.port.get());}}// only initialize if nonSecurePort is greater than 0 and it isnt already running// because of containerPortInitializer belowif (!this.running.get() this.registration.getNonSecurePort() 0) {// 进行主动注册this.serviceRegistry.register(this.registration);// 发布注册事件this.context.publishEvent(new InstanceRegisteredEvent(this, this.registration.getInstanceConfig()));this.running.set(true);}}EurekaServiceRegistry#register() 注册代码如下
Override
public void register(EurekaRegistration reg) {maybeInitializeClient(reg);if (log.isInfoEnabled()) {log.info(Registering application reg.getApplicationInfoManager().getInfo().getAppName() with eureka with status reg.getInstanceConfig().getInitialStatus());}reg.getApplicationInfoManager().setInstanceStatus(reg.getInstanceConfig().getInitialStatus());// 进行注册健康检查reg.getHealthCheckHandler().ifAvailable(healthCheckHandler -reg.getEurekaClient().registerHealthCheck(healthCheckHandler));
}进行安全健康检查同时注册信息 DiscoveryClient#registerHealthCheck()
Overridepublic void registerHealthCheck(HealthCheckHandler healthCheckHandler) {if (instanceInfo null) {logger.error(Cannot register a healthcheck handler when instance info is null!);}if (healthCheckHandler ! null) {this.healthCheckHandlerRef.set(healthCheckHandler);// schedule an onDemand update of the instanceInfo when a new healthcheck handler is registeredif (instanceInfoReplicator ! null) {// 进行注册instanceInfoReplicator.onDemandUpdate();}}}
在上述的onDemandUpdate()方法中有个register方法代码如下 DiscoveryClient#register()
boolean register() throws Throwable {logger.info(PREFIX {}: registering service..., appPathIdentifier);EurekaHttpResponseVoid httpResponse;try { // 发请求给配置url进行注册 httpResponse eurekaTransport.registrationClient.register(instanceInfo);} catch (Exception e) {logger.warn(PREFIX {} - registration failed {}, appPathIdentifier, e.getMessage(), e);throw e;}if (logger.isInfoEnabled()) {logger.info(PREFIX {} - registration status: {}, appPathIdentifier, httpResponse.getStatusCode());}// 返回204码代表注册成功return httpResponse.getStatusCode() 204;}
AbstractJerseyEurekaHttpClient#register()
Override
public EurekaHttpResponseVoid register(InstanceInfo info) {String urlPath apps/ info.getAppName();ClientResponse response null;try {Builder resourceBuilder jerseyClient.resource(serviceUrl).path(urlPath).getRequestBuilder();addExtraHeaders(resourceBuilder);response resourceBuilder.header(Accept-Encoding, gzip).type(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, info);return anEurekaHttpResponse(response.getStatus()).headers(headersOf(response)).build();} finally {if (logger.isDebugEnabled()) {logger.debug(Jersey HTTP POST {}/{} with instance {}; statusCode{}, serviceUrl, urlPath, info.getId(), response null ? N/A : response.getStatus());}if (response ! null) {response.close();}}
}