springCloud -- 微服务01

发布于:2025-07-19 ⋅ 阅读:(23) ⋅ 点赞:(0)

目录

1.单体架构

单体架构就是整个项目中所有功能模块都在一个工程中开发;项目部署时需要对所有模块一起编译、打包;项目的架构设计、开发模式都非常简单。

当项目规模较小时,单体架构上手简单、部署、运维都很方便。但是一旦项目规模变大,例如淘宝那样的,单体架构就远远不够了。

2.微服务

微服务架构就是将单体架构中的功能模块从单体架构中拆分出来,独立部署为多个服务。同时满足以下要求:

  • 单一职责:一个微服务负责一部分业务功能,并且其核心数据不依赖于其它模块。

  • 团队自治:每个微服务都有自己独立的开发、测试、发布、运维人员,团队人员规模不超过10人

  • 服务自治:每个微服务都独立打包部署,访问自己独立的数据库。并且要做好服务隔离,避免对其它服务产生影响

例如上面的商城项目就可以拆分为多个模块,然后独立部署。

3.SpringCloud 

微服务拆分以后碰到的各种问题都有对应的解决方案和微服务组件,而SpringCloud框架可以说是目前Java领域最全面的微服务组件的集合了。

SpringCloud依托于SpringBoot的自动装配能力,大大降低了其项目搭建、组件使用的成本。

在选择SpringCloud版本的时候,一定要选择与SpringBoot相对应的版本。

二、微服务拆分

1.服务拆分原则

拆分微服务时,要保证高内聚、低耦合的原则。即对一个微服务进行修改,不会对另一个微服务产生影响。

服务拆分方式有两种:纵向拆分和横向拆分。

所谓纵向拆分,就是按照项目的功能模块来拆分。例如商城项目中,就有用户管理功能、订单管理功能、购物车功能、商品管理功能、支付功能等。那么按照功能模块将他们拆分为一个个服务,就属于纵向拆分。这种拆分模式可以尽可能提高服务的内聚性。

横向拆分,是看各个功能模块之间有没有公共的业务部分,如果有将其抽取出来作为通用服务。例如用户登录是需要发送消息通知,记录风控数据,下单时也要发送短信,记录风控数据。因此消息发送、风控数据记录就是通用的业务功能,因此可以将他们分别抽取为公共服务:消息中心服务、风控管理服务。这样可以提高业务的复用性,避免重复开发。同时通用业务一般接口稳定性较强,也不会使服务之间过分耦合。

2.服务调用

因为上述的商城项目使用的是单体架构,一个功能可以随意调用另一个功能的方法。但是再拆分之后,两个模块之间没有任何联系。如果购物车业务中需要查询商品信息,此时就需要去访问商品模块,流程如下:

代码中需要变化的是这一步:

3. RestTemplate

Spring给我们提供了一个RestTemplate的API,可以方便的实现Http请求的发送。常见的Get、Post、Put、Delete请求都支持,如果请求参数比较复杂,还可以使用exchange方法来构造请求。

首先,需要在请求服务的微服务模块中定义一个配置类,将RestTemplate注册为一个Bean:

@Configuration
public class RemoteCallConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

之后,在调用服务的Service类中进行远程调用:

此时,购物车模块就可以查询到商品的相关信息了。

在调用之前,要将RestTemplate这个Bean对象进行注入。

三、服务注册和发现

如果上述商品的微服务模块被调用的较多,为了应对更高的并发,进行了多实例部署,如图:

我们会发现,每一个实例的端口都是不一样的(实际上可能ip地址也不相同)。但是在上述代码中我们将ip地址写死了,导致不管部署多少个实例,都只会调用同一个实例。为了解决该问题,就需要引入注册中心的概念。

1. 注册中心原理

在微服务的远程调用过程中,包括两个角色:

  • 服务提供者:提供接口供其它微服务访问,比如item-service

  • 服务消费者:调用其它微服务提供的接口,比如cart-service

在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务就引入了注册中心的概念。注册中心、服务提供者、服务消费者三者间关系如下:

注册中心会知道服务提供者有多少个实例,然后告知服务调用者,服务调用者会采取某一个负载均衡算法来选择一个实例进行访问。如果服务提供者中有某一个实例宕机了,注册中心就会实时更新,告知服务调用者这个示例不可使用,防止白白访问,浪费资源。

2. 服务发现

2.1 服务注册

目前开源的注册中心框架有很多,这里使用阿里巴巴公司出品的Nacos。首先把item-service注册到Nacos(其实可能每一个微服务项目都需要注册,因为可能将来会被调用)。

注册步骤分为两步,添加依赖,进行配置

item-servicepom.xml中添加依赖:

<!--nacos 服务注册发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

item-serviceapplication.yml中添加nacos地址配置,nocos地址改为自己的ip地址。

spring:
  application:
    name: item-service # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848 # nacos地址

完成上述两步之后,就相当于已经注册好了。 

2.2 服务发现

在服务调用者的模块中也要进行上述两步配置。

然后,服务调用者cart-service就可以去订阅item-service服务了。

服务发现需要用到一个工具,DiscoveryClient,SpringCloud已经帮我们自动装配,我们可以直接注入使用:

然后对原来的远程调用进行修改,将写死的ip和端口改为方法调用来获取:

四、OpenFeign

我们发现修改之后的代码,从一行变成了九行,使用RestTemplate实现服务的远程调用增加了代码的复杂度。为了简化代码,就需要用到OpenFeign组件了。

1.1 首先在购物车微服务模块中引入OpenFeign的依赖和loadBalancer依赖:

  <!--openFeign-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>
  <!--负载均衡器-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  </dependency>

1.2 在购物车启动类中上添加注解,启动OpenFeign功能:

1.3 编写OpenFeign客户端:

在模块中,定义一个新的接口,编写Feign客户端,这里是定义了一个商品模块的客户端。

package com.hmall.cart.client;

import com.hmall.cart.domain.dto.ItemDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@FeignClient("item-service")
public interface ItemClient {

    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

1.4 使用FeignClient:

首先在代码中注入ItemClient,然后直接调用ItemClient中的方法。这里我理解的是购物车模块通过客户端调用该方法,就相当于在浏览器中直接访问ip(这里不是通过浏览器,而是通过Nacos),然后商品模块中的相应方法就会执行,查询数据库之后将结果进行返回。


网站公告

今日签到

点亮在社区的每一天
去签到