spring cloud学习笔记02

本文介绍SpringCloud及其核心组件,强调其在微服务架构中的角色。文章解析SpringBoot简化开发流程的特点,并探讨SpringCloud如何利用SpringBoot实现高效微服务开发。此外,还深入介绍了Eureka服务注册与发现机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

spring cloud 介绍

从 Spring Boot 到 Spring Cloud

Spring Cloud 具备一个天生的优势,因为它是 Spring 家庭的一员,而 Spring 在 Java EE 开发领域的强大地位,给 Spring Cloud 起到很好的推动作用。同时,Spring Cloud 所基于的 Spring Boot,已经成为 Java EE 领域中最流行的开发框架,用来简化 Spring 应用程序的框架搭建和开发过程。

在微服务架构中,我们将通过 Spring Boot 来开发单个微服务。同样作为 Spring 家族的新成员,Spring Boot 提供了令人兴奋的特性,这些特性主要体现在开发过程的简单化,包括支持快速构建项目、不依赖外部容器独立运行、开发部署效率高,以及与云平台天然集成等。而在微服务架构中,Spring Cloud 构建在 Spring Boot 之上,继承了 Spring Boot 的多项功能特性,使得开发微服务变得简单而高效。

在设计思想上,Spring Boot 充分利用约定优于配置(Convention over Configuration)的自动化配置机制。与传统的 Spring 应用程序相比, Spring Boot 在启动依赖项自动管理、简化部署并提供应用监控等方面对开发过程做了优化

Spring Cloud 中的核心组件

Spring Cloud Netflix 组件,其中集成了 Netflix OSS 的 Eureka 注册中心、Zuul 网关、Hystrix 熔断器等工具
在这里插入图片描述

服务治理的基本需求

在微服务架构中,任何一个服务既可以是服务的提供者,也可以是服务的消费者(调用者)。围绕服务消费者如何调用服务提供者这个问题,需要进行服务的治理。

服务治理最基本的需求是要支持服务的注册和发现,而且这个过程是自动的。

高可用,构建高可用集群,服务只要连接集群中的任何一台注册中心完成服务的注册和发现即可。单台服务器的宕机不影响服务的正常运行。

注册中心是一种服务器组件

难度在于服务实例变更时,如何同步到服务的消费者?从架构设计上讲,状态变更管理可以采用发布-订阅模式,服务提供者可以根据服务定义发布服务。发布订阅采用监听机制或主动拉取的轮询策略。

服务治理实现工具

Consul
Zookeeper 采用监听机制
Netflix Eureka 采用轮询(默认同步频率为30
s)

基于Eureka构建注册中心

构建单个Eureka服务

一、引入依赖

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
		</dependency>

EurekaServerApplication

package com.springhealth.eurekaserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

在这里插入图片描述
客户端配置


server:
  port: 8761

eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://localhost:8761
  server:
    waitTimeInMsWhenSyncEmpty: 0

logging:
    level:
      com.netflix: WARN
      org.springframework.web: WARN
      com.tianyalan: INFO

    

构建Eureka服务器集群

peer awareness 模式
application-eureka1.yml

server:
  port: 8761
eureka:
  instance:
    hostname: eureka1
  client
    serviceUrl
	   defaultZone: http:// eureka2:8762/eureka/

application-eureka2.yml

server:
  port: 8762
eureka:
  instance:
    hostname: eureka2
  client
    serviceUrl
	   defaultZone: http://eureka1:8761/eureka/

Eureka服务器实现原理

多台Eureka相互注册形成集群,服务提供者可以向注册中心注册、续约、取消
服务消费者可以中注册中心中获取注册信息来进行调用。

显然对于一个注册中心而言,要理解它的设计理念,需要关注Eureka如何对服务注册信息的存储和管理的具体机制。

Eureka的服务存储和缓存处理

InstanceRegistry 接口的实现类 AbstractInstanceRegistry 中发现了 Eureka 用于保存注册信息的数据结构

private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry =
 new ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();

而对于 InstanceRegistry 本身,它也继承了 Eureka 中两个非常重要的接口,即LeaseManager 接口和 LookupService 接口

public interface LeaseManager<T> {

    void register(T r, int leaseDuration, boolean isReplication);

    boolean cancel(String appName, String id, boolean isReplication);

    boolean renew(String appName, String id, boolean isReplication);

    void evict();

}

显然 LeaseManager 做的事情就是 Eureka 注册中心模型中的服务注册、服务续约、服务取消和服务剔除等核心操作,关注于对服务注册过程的管理。而 LookupService 接口定义如下,关注于对应用程序与服务实例的管理:

public interface LookupService<T> {

    Application getApplication(String appName);

    Applications getApplications();

    List<InstanceInfo> getInstancesById(String id);

    InstanceInfo getNextServerFromEureka(String virtualHostname, boolean secure);

}

Eureka 客户端并理解其实现原理

一、引入依赖

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>

UserApplication

package com.springhealth.user;

import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;

@SpringCloudApplication
public class UserApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

application.yml

server:
  port: 8082

spring:
  cloud:
    config:
     enabled: true
     uri: http://localhost:8888
      
logging:
    level:
      com.netflix: WARN
      org.springframework.web: WARN
      com.tianyalan: INFO

eureka:
  instance:
    preferIpAddress: true
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
        defaultZone: http://localhost:8761/eureka/
       

serviceUrl.defaultZone 指定的就是 Eureka 服务器的地址。

获取注册到 Eureka 服务器上具体某一个服务实例的详细信息,我们可以访问如下地址:
http://<eureka-ip-port>:8761/eureka/apps/<APPID>

例如浏览器输入 http://localhost:8761/eureka/apps/userservice

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<application>
<name>USERSERVICE</name>
<instance>
<instanceId>192.168.1.11:userservice:8083</instanceId>
<hostName>192.168.1.11</hostName>
<app>USERSERVICE</app>
<ipAddr>192.168.1.11</ipAddr>
<status>UP</status>
<overriddenstatus>UNKNOWN</overriddenstatus>
<port enabled="true">8083</port>
<securePort enabled="false">443</securePort>
<countryId>1</countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30</renewalIntervalInSecs>
<durationInSecs>90</durationInSecs>
<registrationTimestamp>1608016285007</registrationTimestamp>
<lastRenewalTimestamp>1608016464974</lastRenewalTimestamp>
<evictionTimestamp>0</evictionTimestamp>
<serviceUpTimestamp>1608016285007</serviceUpTimestamp>
</leaseInfo>
<metadata>
<management.port>8083</management.port>
<jmx.port>50708</jmx.port>
</metadata>
<homePageUrl>http://192.168.1.11:8083/</homePageUrl>
<statusPageUrl>http://192.168.1.11:8083/actuator/info</statusPageUrl>
<healthCheckUrl>http://192.168.1.11:8083/actuator/health</healthCheckUrl>
<vipAddress>userservice</vipAddress>
<secureVipAddress>userservice</secureVipAddress>
<isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1608016285007</lastUpdatedTimestamp>
<lastDirtyTimestamp>1608016284958</lastDirtyTimestamp>
<actionType>ADDED</actionType>
</instance>
<instance>
<instanceId>192.168.1.11:userservice:8082</instanceId>
<hostName>192.168.1.11</hostName>
<app>USERSERVICE</app>
<ipAddr>192.168.1.11</ipAddr>
<status>UP</status>
<overriddenstatus>UNKNOWN</overriddenstatus>
<port enabled="true">8082</port>
<securePort enabled="false">443</securePort>
<countryId>1</countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30</renewalIntervalInSecs>
<durationInSecs>90</durationInSecs>
<registrationTimestamp>1608018298663</registrationTimestamp>
<lastRenewalTimestamp>1608019318854</lastRenewalTimestamp>
<evictionTimestamp>0</evictionTimestamp>
<serviceUpTimestamp>1608016335919</serviceUpTimestamp>
</leaseInfo>
<metadata>
<management.port>8082</management.port>
<jmx.port>51602</jmx.port>
</metadata>
<homePageUrl>http://192.168.1.11:8082/</homePageUrl>
<statusPageUrl>http://192.168.1.11:8082/actuator/info</statusPageUrl>
<healthCheckUrl>http://192.168.1.11:8082/actuator/health</healthCheckUrl>
<vipAddress>userservice</vipAddress>
<secureVipAddress>userservice</secureVipAddress>
<isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1608018298663</lastUpdatedTimestamp>
<lastDirtyTimestamp>1608018298634</lastDirtyTimestamp>
<actionType>ADDED</actionType>
</instance>
</application>

Eureka 客户端基本原理

对于 Eureka 而言,微服务的提供者和消费者都是它的客户端,其中服务提供者关注服务注册、服务续约和服务下线等功能,而服务消费者关注于服务信息的获取。同时,对于服务消费者而言,为了提高服务获取的性能以及在注册中心不可用的情况下继续使用服务,一般都还会具有缓存机制。

boolean register() throws Throwable {
        EurekaHttpResponse<Void> httpResponse;
        try {
            httpResponse = eurekaTransport.registrationClient.register(instanceInfo);
        } catch (Exception e) {
            throw e;
        }
        return httpResponse.getStatusCode() == 204;
}

上述 register 方法会在 InstanceInfoReplicator 类的 run 方法中进行执行。从操作流程上讲,上述代码的逻辑非常简单,即服务提供者先将自己注册到 Eureka 服务器中,然后根据返回的结果确定操作是否成功。显然,这里的重点代码是eurekaTransport.registrationClient.register(),DiscoveryClient 通过这行代码发起了远程请求。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值