基于Spring Cloud的微服务落地(上)

简介: 基于Spring Cloud的微服务落地(上)

微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务。但如果要将微服务架构运用到生产项目上,并且能够发挥该架构模式的重要作用,则需要微服务框架的支持。

在Java生态圈,目前使用较多的微服务框架就是集成了包括Netfilix OSS以及Spring的Spring Cloud。它包括:

  • Spring Cloud Config:配置管理工具,支持使用Git存储配置内容,可以实现应用配置的外部化存储,支持客户端配置信息刷新、加密/解密配置内容等。
  • Spring Cloud Netflix:对Netflix OSS进行了整合。其中又包括:
  • Eureka:服务治理组件,包含服务注册中心、服务注册与发现。
  • Hystrix:容器管理组件,实现断路器模式,倘若依赖的服务出现延迟或故障,则提供强大的容错功能。
  • Ribbon:客户端负载均衡的服务调用组件。
  • Feign:基于Ribbon和Hystrix的声明式服务调用组件。
  • Zuul:网关组件,提供智能路由、访问过滤等功能。
  • Archaius:外部化配置组件。
  • Spring Cloud Bus:事件、消息总线。
  • Spring Cloud Cluster:针对ZooKeeper、Redis、Hazelcast、Consul的选举算法和通用状态模式的实现。
  • Spring Cloud Cloudfoundry:与Pivotal Cloudfoundry的整合支持。
  • Spring Cloud Consul:服务发现与配置管理工具。
  • Spring Cloud Stream:通过Redis、Rabbit或者Kafka实现的消息驱动的微服务。
  • Spirng Cloud AWS:简化和整合Amazon Web Service。
  • Spring Cloud Security:安全工具包,提供Zuul代理中对OAuth2客户端请求的中继器。
  • Spring Cloud Sleuth:Spring Cloud应用的分布式跟踪实现,可以整合Zipkin。
  • Spring Cloud ZooKeeper:基于ZooKeeper的服务发现与配置管理组件。
  • Spring Cloud Starters:Spring Cloud的基础组件,是基于Spring Boot风格项目的基础依赖模块。
  • Spring Cloud CLI:用于在Groovy中快速创建Spring Cloud应用的Spring Boot CLI插件。

服务治理


当一个系统的微服务数量越来越多的时候,我们就需要对服务进行治理,提供统一的服务注册中心,然后在其框架下提供发现服务的功能。这样就避免了对多个微服务的配置,以及微服务之间以及与客户端之间的耦合。

Spring Cloud Eureka是对Netflix Eureka的包装,用以实现服务注册与发现。Eureka服务端即服务注册中心,支持高可用配置。它依托于强一致性提供良好的服务实例可用性,并支持集群模式部署。Eureka客户端则负责处理服务的注册与发现。客户端服务通过annotation与参数配置的方式,嵌入在客户端应用程序代码中。在运行应用程序时,Eureka客户端向注册中心注册自身提供的服务,并周期性地发送心跳更新它的服务租约。


搭建服务注册中心


服务注册中心是一个独立部署的服务(你可以认为它也是一个微服务),所以需要单独为它创建一个项目,并在pom.xml中添加Eureka的依赖:

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

创建Spring Boot Application:

@EnableEurekaServer
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }
}


注册服务提供者


要让自己编写的微服务能够注册到Eureka服务器中,需要在服务的Spring Boot Application中添加@EnableDiscoveryClient注解,如此才能让Eureka服务器发现该服务。当然,pom.xml文件中也需要添加相关依赖:

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

同时,我们还需要为服务命名,并指定地址。这些信息都可以在application.properties配置文件中配置:

spring.application.name=demo-service
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/


说明:Spring更推荐使用yml文件来维护系统的配置,yml文件可以体现出配置节的层次关系,表现力比单纯的key-value形式更好。如果结合使用后面讲到的Spring Cloud Config,则客户端的配置文件必须命名为bootstrap.properties或者bootstrap.yml。与上述配置相同的yml文件配置为:

spring:
  application:
    name: demo-service
eureka:
  client:
    serviceUrl: 
      defaultZone: http://localhost:1111/eureka/


服务发现与消费


在微服务架构下,许多微服务可能会扮演双重身份。一方面它是服务的提供者,另一方面它又可能是服务的消费者。注册在Eureka Server中的微服务可能会被别的服务消费。此时,就相当于在服务中创建另一个服务的客户端,并通过RestTemplate发起对服务的调用。为了更好地提高性能,可以在服务的客户端引入Ribbon,作为客户端负载均衡。

现在假定我们要为demo-service创建一个服务消费者demo-consumer。该消费者自身也是一个Spring Boot微服务,同时也能够被Eureka服务器注册。这时,就需要在该服务的pom.xml中添加eureka与ribbon的依赖:

<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>

然后在主应用类ConosumerApplication中注入RestTemplate,并引入@LoadBalanced注解开启客户端负载均衡:

@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args)
    }
}

假设消费demo-service的客户端代码写在demo-consumer服务的其中一个Controller中:

@RestController
public class ConsumerController {
    @Autowired
    RestTemplate restTemplate;
    @RequestMapping(value = "/demo-consumer", method = RequestMethod.Get)
    public String helloConsumer() {
        return restTemplate.getForEntity("http://demo-service/demo", String.class).getBody(); 
    }
}

通过RestTemplate就可以发起对demo-service的消费调用。


声明式服务调用


通过Ribbon和Hystrix可以实现对微服务的调用以及容错保护,但Spring Cloud还提供了另一种更简单的声明式服务调用方式,即Spring Cloud Feign。Feign实际上就是对Ribbon与Hystrix的进一步封装。通过Feign,我们只需创建一个接口并用annotation的方式配置,就可以完成对服务供应方的接口(REST API)绑定。

假设我们有三个服务:

  • Notification Service
  • Account Service
  • Statistics Service

服务之间的依赖关系如下图所示:

image.png

要使用Feign来完成声明式的服务调用,需要在作为调用者的服务中创建Client。Client通过Eureka Server调用注册的对应服务,这样可以解除服务之间的耦合。结构如下图所示:

image.png

为了使用Feign,需要对应微服务的pom.xml文件中添加如下依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

同时,还需要在被消费的微服务Application中添加@EnableFeignClients注解。例如在Statistics服务的应用程序类中:

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

由于Account服务需要调用Statistics服务,因此需要在Account服务项目中增加对应的client接口:

@FeignClient(name = "statistics-service")
public interface StatisticsServiceClient {
    @RequestMapping(method = RequestMethod.PUT, value = "/statistics/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    void updateStatistics(@PathVariable("accountName") String accountName, Account account);
}

StatisticsServiceClient接口的updateStatistics()方法会调用URI为/statistics/{accountName}的REST服务,且HTTP动词为put。这个服务其实对应就是Statistics Service中StatisticsController类中的saveStatistics()方法:

@RestController
public class StatisticsController {
    @Autowired
    private StatisticsService statisticsService;
    @RequestMapping(value = "/{accountName}", method = RequestMethod.PUT)
    public void saveStatistics(@PathVariable String accountName, @Valid @RequestBody Account account) {
        statisticsService.save(accountName, account);
    }
}

在Account服务中,如果要调用Statistics服务,都应该通过StatisticsServiceClient接口进行调用。例如,Account服务中的AccountServiceImpl要调用updateStatistics()方法,就可以在该类的实现中通过@autowired注入StatisticsServiceClient接口:

@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    private StatisticsServiceClient statisticsClient;
    @Autowired
    private AccountRepository repository;
    @Override
    public void saveChanges(String name, Account update) {
        //...
        statisticsClient.updateStatistics(name, account);
    }
}

Notification服务对Account服务的调用如法炮制。



相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
9月前
|
算法 Java 微服务
【SpringCloud(1)】初识微服务架构:创建一个简单的微服务;java与Spring与微服务;初入RestTemplate
微服务架构是What?? 微服务架构是一种架构模式,它提出将单一应用程序划分为一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。 每个服务允许在其独立的进程中,服务于服务间采用轻量级的通信机制互相协作(通常是Http协议的RESTful API或RPC协议)。 每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据上下文,选择合适的语言、工具对其进行构建
718 126
|
9月前
|
负载均衡 算法 Java
【SpringCloud(2)】微服务注册中心:Eureka、Zookeeper;CAP分析;服务注册与服务发现;单机/集群部署Eureka;连接注册中心
1. 什么是服务治理? SpringCloud封装了Netfix开发的Eureka模块来实现服务治理 在传统pc的远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册
485 0
|
10月前
|
数据可视化 Java BI
将 Spring 微服务与 BI 工具集成:最佳实践
本文探讨了 Spring 微服务与商业智能(BI)工具集成的潜力与实践。随着微服务架构和数据分析需求的增长,Spring Boot 和 Spring Cloud 提供了构建可扩展、弹性服务的框架,而 BI 工具则增强了数据可视化与实时分析能力。文章介绍了 Spring 微服务的核心概念、BI 工具在企业中的作用,并深入分析了两者集成带来的优势,如实时数据处理、个性化报告、数据聚合与安全保障。同时,文中还总结了集成过程中的最佳实践,包括事件驱动架构、集中配置管理、数据安全控制、模块化设计与持续优化策略,旨在帮助企业构建高效、智能的数据驱动系统。
465 1
将 Spring 微服务与 BI 工具集成:最佳实践
|
10月前
|
Java 数据库 数据安全/隐私保护
Spring 微服务和多租户:处理多个客户端
本文介绍了如何在 Spring Boot 微服务架构中实现多租户。多租户允许单个应用实例为多个客户提供独立服务,尤其适用于 SaaS 应用。文章探讨了多租户的类型、优势与挑战,并详细说明了如何通过 Spring Boot 的灵活配置实现租户隔离、动态租户管理及数据源路由,同时确保数据安全与系统可扩展性。结合微服务的优势,开发者可以构建高效、可维护的多租户系统。
803 127
|
10月前
|
存储 安全 Java
管理 Spring 微服务中的分布式会话
在微服务架构中,管理分布式会话是确保用户体验一致性和系统可扩展性的关键挑战。本文探讨了在 Spring 框架下实现分布式会话管理的多种方法,包括集中式会话存储和客户端会话存储(如 Cookie),并分析了它们的优缺点。同时,文章还涵盖了与分布式会话相关的安全考虑,如数据加密、令牌验证、安全 Cookie 政策以及服务间身份验证。此外,文中强调了分布式会话在提升系统可扩展性、增强可用性、实现数据一致性及优化资源利用方面的显著优势。通过合理选择会话管理策略,结合 Spring 提供的强大工具,开发人员可以在保证系统鲁棒性的同时,提供无缝的用户体验。
222 0
|
10月前
|
消息中间件 Java 数据库
Spring 微服务中的数据一致性:最终一致性与强一致性
本文探讨了在Spring微服务中实现数据一致性的策略,重点分析了最终一致性和强一致性的定义、优缺点及适用场景。结合Spring Boot与Spring Cloud框架,介绍了如何根据业务需求选择合适的一致性模型,并提供了实现建议,帮助开发者在分布式系统中确保数据的可靠性与同步性。
621 0
|
10月前
|
监控 Java 数据库
从零学 Dropwizard:手把手搭轻量 Java 微服务,告别 Spring 臃肿
Dropwizard 整合 Jetty、Jersey 等成熟组件,开箱即用,无需复杂配置。轻量高效,启动快,资源占用少,内置监控、健康检查与安全防护,搭配 Docker 部署便捷,是构建生产级 Java 微服务的极简利器。
1029 117
|
9月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1384 2
Spring Boot 3.x 微服务架构实战指南
|
9月前
|
负载均衡 Java API
《深入理解Spring》Spring Cloud 构建分布式系统的微服务全家桶
Spring Cloud为微服务架构提供一站式解决方案,涵盖服务注册、配置管理、负载均衡、熔断限流等核心功能,助力开发者构建高可用、易扩展的分布式系统,并持续向云原生演进。