面对环视的强敌,我一直问自己这样一个问题:现在开始还来得及吗?面对残酷的现实世界,我也不断寻找让自己躺平的理由,可没有一个理由可以让我坦然接受现在的一切。于是,我决定强攻!可这满头乱发,该如何抓呢?好不容易揪住一根银丝,却不知道应该如何开始!只能日日唉声叹气,毫无进展!可一切总要有个说法,徒自烦闷终是于事无补。因此我决定暂时放弃微服务理论部分的知识,直接学习微服务框架Spring Cloud的用法,同时研究其源码。

1 Spring Cloud是什么?

学习一个东西,我们首先要弄清楚三个问题:是什么,干什么,怎么用。下面先来看一下通义千问大模型关于Spring Cloud的描述:

Spring Cloud是一个由Pivotal团队提供的基于Java的微服务工具集,它为开发者设计并实现微服务架构提供了全面的解决方案。Spring Cloud构建在Spring Boot之上,其核心目标是简化分布式系统和服务的开发流程,通过一系列的开源组件和工具,为开发者提供了服务发现注册、配置管理、熔断器、智能路由、微代理、控制总线、一次性令牌、全局锁、主节点选举、分布式会话、集群状态管理等分布式系统中常见的功能模块。

简而言之,Spring Cloud是一个针对微服务架构设计的标准化一站式开发框架,它通过整合和封装各种成熟的第三方库和服务,为开发者提供了一整套开箱即用的微服务开发工具及最佳实践,使得在搭建和管理分布式系统时能更高效、更便捷,从而更好地应对云计算环境下的服务治理挑战。

通过这段描述,我们可以得出这样一些信息:Spring Cloud是一套基于Java的微服务工具集,为开发者提供了在分布式系统(微服务架构)中快速构建、部署和管理微服务的一站式解决方案。它是在Spring Boot基础上创建的,用于简化分布式系统和服务的复杂性,促进各服务间的协同工作和统一管理。Spring Cloud整合并封装了一系列经过实战检验的成熟框架和组件,譬如:

服务注册与发现:通过 Eureka 或 ZooKeeper 提供服务注册与发现机制负载均衡与服务调用:利用 Ribbon 和 Feign 进行客户端负载均衡和服务调用断路器:采用 Hystrix 实现服务容错和断路器模式,保护服务免受级联故障的影响网关服务:借助 Zuul 或 Spring Cloud Gateway 实现 API 路由、过滤、安全控制等功能配置中心:使用 Spring Cloud Config 分布式管理不同环境下的应用配置服务跟踪:结合 Zipkin 或 Sleuth 可以实现实时监控和全链路追踪消息队列支持:通过与 RabbitMQ 或 Kafka 集成,实现异步消息处理控制总线和分布式事务支持:如通过 Spring Cloud Bus 实现事件驱动的配置刷新等

2 Spring Cloud怎么用?

通过第一小节,我们了解了Spring Cloud的定义,同时也知道了Spring Cloud可以用来做些什么?可是对于这个工具如何使用,我们却鲜有提及。这一小节我们就来重点聊聊Spring Cloud的用法。然而,因为Spring Cloud是一套微服务工具集,其涉及的框架和组件非常多,譬如:服务注册与发现、负载均衡与服务调用、网关服务、配置中心、断路器、服务跟踪等等,所以想在一小节中就把Spring Cloud的用法完全弄懂是不太现实的。这就好比想一口吃成胖子,实属一厢情愿。但是,我们也不能因此放弃对这个框架用法的讨论!因此本小节我们将从一个小点(Spring Cloud中的注册中心组件)开始,通过对这个小点的分析(学习这个组件的基本用法),然后逐步攻克Spring Cloud这座高大的城池(学会Spring Cloud的用法)。在开始前,我们要先了解一下注册中心这个概念。

注册中心,在分布式系统特别是微服务架构中,是一种服务注册与发现的关键组件。它本质上是一个服务注册表(service registry),用于存储和管理各个服务实例的服务元数据和网络位置信息(如IP地址、端口号),确保服务间的相互调用能够准确高效地找到对方。具体来说,注册中心的作用有:

服务注册:服务提供方启动时,将自己提供的服务信息(服务名、服务地址、健康状态等)注册到注册中心服务发现:服务消费方需要调用某个服务时,向注册中心查询所需服务的可用实例列表,获取服务提供方的具体访问地址心跳检测与实例管理:注册中心通过心跳机制与服务实例保持连接,实时更新服务实例的状态,比如剔除掉不健康的或者已经下线的服务实例服务路由与负载均衡:虽然注册中心本身并不直接提供负载均衡功能,但它可以配合外部的负载均衡器或客户端内部的负载均衡策略,实现对服务消费者的透明化服务路由

在实际应用中,常见的注册中心产品和技术有:

Netflix Eureka:由Netflix开发的服务注册与发现组件,广泛应用于基于Spring Cloud构建的微服务系统中HashiCorp Consul:除了服务注册与发现外,还提供了KV存储、健康检查等功能Apache ZooKeeper:虽然不是专门设计为服务注册中心,但在很多场景下可以用来实现服务注册与发现Alibaba Nacos:阿里巴巴开源的一个更综合的服务发现、配置管理和服务管理平台。

无论如何,通过注册中心,微服务架构得以灵活扩展和动态调整,实现了服务间松耦合和高可用性。下面就来看看如何利用Spring Cloud中的Eureka组件来实现一个注册中心吧!

2.1 创建Eureka注册中心

首先创建一个Maven项目,取名为eureka-server。然后在项目中的pom.xml文件中配置Eureka依赖信息,该文件的详细信息如下所示:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.com.chinasoft

springcloud-eureka-server

1.0-SNAPSHOT

jar

springcloud-eureka-server

org.springframework.boot

spring-boot-starter-parent

1.5.7.RELEASE

UTF-8

1.7

1.7

org.springframework.cloud

spring-cloud-starter-netflix-eureka-server

junit

junit

3.8.1

test

org.springframework.cloud

spring-cloud-dependencies

Edgware.SR5

pom

import

注意:上述代码中的spring-cloud-starter-netflix-eureka-server,就是我们要引入项目中的eureka依赖。

接着编写启动类。该启动的名字为EurekaServerApplication。其源码详细如下所示(注意这个类上的注解@EnableEurekaServer,它表示开启Eureka Server):

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**

*

*/

@SpringBootApplication

@EnableEurekaServer // 当前使用eureka的server

public class EurekaServerApplication {

public static void main(String[] args) {

SpringApplication.run(EurekaServerApplication.class, args);

}

}

最后编写项目配置文件,即application.yml。在该配置文件中添加相关配置项,譬如:项目名称(spring.application.name)、端口(server.port)等。配置文件详细信息如下所示:

server:

port: 8700 # 端口自己决定

# 指定当前eureka客户端的注册地址,也就是eureka服务的提供方,当前配置的服务的注册服务方

eureka:

client:

service-url:

defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka

register-with-eureka: false #自身 不在向eureka注册

fetch-registry: false #启动时禁用client的注册

instance:

hostname: localhost

#指定应用名称

spring:

application:

name: eureka-server

2.2 创建服务提供者

接着创建一个Maven项目,取名为eureka-client。然后在项目中的pom.xml文件中配置相关依赖信息,该文件的详细信息如下所示:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.com.chinasoft

springcloud-eureka-client

1.0-SNAPSHOT

jar

springcloud-eureka-client

org.springframework.boot

spring-boot-starter-parent

1.5.7.RELEASE

UTF-8

1.7

1.7

org.springframework.cloud

spring-cloud-starter-netflix-eureka-client

junit

junit

3.8.1

test

org.springframework.cloud

spring-cloud-dependencies

Edgware.SR5

pom

import

注意:上述代码中的spring-cloud-starter-netflix-eureka-client,就是我们要引入项目中的eureka依赖。

接着编写启动类。该启动的名字为EurekaServiceApplication。其源码详细如下所示(注意这个类上的注解@EnableDiscoveryClient,它表示当前服务是一个Eureka的客户端):

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**

*

*/

@SpringBootApplication

@EnableDiscoveryClient // 代表自己是一个服务提供方

public class EurekaServiceApplication {

public static void main(String[] args) {

SpringApplication.run(EurekaServiceApplication.class, args);

}

}

再次编写Controller类,其中控制器用于接收客户端请求。这个Controller类的详细代码如下所示:

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

@RequestMapping("/Hello")

public class Controller {

@RequestMapping("/World")

public String helloWorld(String s) {

System.out.println("传入的值为:" + s);

return "传入的值为:" + s;

}

}

最后编写项目配置文件,即application.yml。在该配置文件中添加相关配置项,譬如:项目名称(spring.application.name)、端口(server.port)等。配置文件详细信息如下所示:

server:

port: 8701 # 服务提供方

# 指定当前eureka客户端的注册地址,

eureka:

client:

service-url:

defaultZone: http://${eureka.instance.hostname}:8700/eureka

instance:

hostname: localhost

#当前服务名称

spring:

application:

name: eureka-service

2.3 创建服务消费者

接着创建一个Maven项目,取名为eureka-consumer。然后在项目中的pom.xml文件中配置相关依赖信息,该文件的详细信息如下所示:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.com.chinasoft

eureka-consumer

1.0-SNAPSHOT

jar

springcloud-ribbon

org.springframework.boot

spring-boot-starter-parent

1.5.7.RELEASE

UTF-8

1.7

1.7

org.springframework.cloud

spring-cloud-starter-netflix-eureka-client

org.springframework.cloud

spring-cloud-starter-ribbon

junit

junit

3.8.1

test

org.springframework.boot

spring-boot-starter-web

org.springframework.cloud

spring-cloud-dependencies

Edgware.SR5

pom

import

注意:上述代码中的spring-cloud-starter-netflix-eureka-client和spring-cloud-starter-ribbon,就是我们要引入到项目中的依赖。

接着编写启动类。该启动的名字为EurekaConsumerApplication。其源码详细如下所示(注意这个类上的注解@EnableDiscoveryClient,它表示当前服务是一个Eureka的客户端):

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication

@EnableDiscoveryClient // 当前使用eureka的server

public class EurekaConsumerApplication {

public static void main(String[] args) {

SpringApplication.run(EurekaConsumerApplication.class, args);

}

}

再次编写Controller和配置类,其中控制器用于接收客户端请求,配置类用于向容器中注入关键对象,其详细代码如下所示:

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cloud.client.ServiceInstance;

import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.client.RestTemplate;

@RestController

@RequestMapping("/Hello")

public class ConsumerController {

@Autowired

private LoadBalancerClient loadBalancerClient;

@Autowired

private RestTemplate restTemplate;

@RequestMapping("/Consumer")

public String helloWorld(String s) {

System.out.println("传入的值为:" + s);

//第一种调用方式

//String forObject = new RestTemplate().getForObject("http://localhost:8071/Hello/World?s=" + s, String.class);

//第二种调用方式

//根据服务名 获取服务列表 根据算法选取某个服务 并访问某个服务的网络位置。

// ServiceInstance serviceInstance = loadBalancerClient.choose("EUREKA-SERVICE");

// String forObject = new RestTemplate().getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/Hello/World?s="+s,String.class);

//第三种调用方式 需要restTemplate注入的方式

String forObject = restTemplate.getForObject("http://EUREKA-SERVICE/Hello/World?s=" + s, String.class);

return forObject;

}

}

import org.springframework.cloud.client.loadbalancer.LoadBalanced;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.client.RestTemplate;

@Configuration

public class Beans {

//管理简单对象

@Bean

@LoadBalanced

public RestTemplate getRestTemplate(){

return new RestTemplate();

}

}

最后编写项目配置文件,即application.yml。在该配置文件中添加相关配置项,譬如:项目名称(spring.application.name)、端口(server.port)等。配置文件详细信息如下所示:

server:

port: 8702 # 服务消费方

# 指定当前eureka客户端的注册地址,

eureka:

client:

service-url:

defaultZone: http://${eureka.instance.hostname}:8700/eureka

instance:

hostname: localhost

#当前服务名称

spring:

application:

name: eureka-consumer

3 总结

通过这篇文章,我对Spring Cloud有了初步的了解:Spring Cloud是一个基于Java的微服务工具集,它为开发者设计并实现微服务架构提供了全面的解决方案。因此个人理解Spring Cloud就是一个方便开发者开发分布式项目的工具集。其整合并封装了一系列经过实战检验的成熟框架和组件,譬如:服务注册与发现、负载均衡与服务调用、网关服务、配置中心、断路器、服务跟踪等等,同时Spring Cloud还对消息队列、控制总线和分布式事务提供了支持。总而言之,通过Spring Cloud工程师可以很容易的设计和开发出一套具有可靠性能的分布式应用。

又是通过这篇文章,我对注册中心这个概念有了基本了解:注册中心,在分布式系统尤其是微服务架构中,是一种服务注册与发现的关键组件。其本质上是一个服务注册表(service registry),用于存储和管理各个服务实例的网络位置信息(如IP地址、端口号)和服务元数据,确保服务间的相互调用能够准确高效地找到对方。总体来看,注册中心就是一个类似于操作系统的注册表,通过这个注册表我们能够很容易的找到自己想用的服务。

最后还是通过这篇文章,我对Spring Cloud这个工具集中的Eureka组件的用法有了一定的了解:知道了如何编写Eureka服务方(即注册中心)、如何编写Eureka服务(即服务提供者)、如何编写Eureka消费者。但是这些信息是如何被Eureka管理的呢?服务提供者是如何注册到Eureka服务端(注册中心的)?服务提供者和Eureka服务端之间是通过什么形式的连接通讯的?Eureka服务端是如何知道服务提供者的状态的(上线、下线)?Eureka消费者是如何从Eureka服务端拉取存活的服务的?Eureka消费者是如何调用Eureka服务提供者的?等等,这些问题都需要我们通过后续的文章一步步深入梳理。

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: