跳到主要内容

分布式组件使用

SpringCloud Alibaba

eureka停止维护,这里使用spring cloud Alibaba

根据spring cloud Alibaba 技术搭配方案:https://github.com/alibaba/spring-cloud-alibaba/blob/2022.x/README-zh.md

  • SpringCloud Alibaba - Nacos:注册中心(服务发现/注册)
  • SpringCloud Alibaba - Nacos:配置中心(动态配置管理)(相当于替换eureka)
  • SpringCloud - Ribbon:负载均衡
  • SpringCloud - Feign:声明式 HTTP 客户端(调用远程服务)
  • SpringCloud Alibaba - Sentinel:服务容错(限流、降级、熔断)
  • SpringCloud - Gateway:API 网关(webflux 编程模式)
  • SpringCloud - Sleuth:调用链监控
  • SpringCloud Alibaba - Seata:原 Fescar,即分布式事务解决方案

导入依赖到common模块:

    <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Nacos注册中心

Mac启动nacos

 sh startup.sh -m standalone

导入到common模块:

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

在其他模块如coupon中:

spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 # nacos服务注册中心地址
application:
name: gulimall-coupon # 应用名称

在启动类上面加注解EnableDiscoveryClient:

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

启动后:

image-20240119152447916

OpenFeign远程调用

导入依赖到每个模块

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

写一个接口:

@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
@Autowired
private CouponService couponService;

@RequestMapping("/member/list")
public R membercoupons(){
CouponEntity couponEntity = new CouponEntity();
couponEntity.setCouponName("满100减10");
return R.ok().put("coupons", Arrays.asList(couponEntity));
}
}

在member模块进行远程调用:

package com.cxk.gulimall.member.feign;

import com.cxk.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient("gulimall-coupon")
public interface CouponFeignService {
@RequestMapping("/coupon/coupon/member/list")
public R membercoupons();
}

image-20240119155651100

启动类添加EnableFeignClients注解

@EnableFeignClients(basePackages="com.cxk.gulimall.member.feign")
@SpringBootApplication
@EnableDiscoveryClient // 开启服务注册发现功能
public class GulimallMemberApplication {

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

}

在MemberController中进行远程调用

@RestController
@RequestMapping("member/member")
public class MemberController {
@Autowired
private MemberService memberService;

@Autowired
private CouponFeignService couponFeignService;

@RequestMapping("/coupons")
public R test(){
MemberEntity memberEntity = new MemberEntity();
memberEntity.setNickname("张三");
R membercoupons = couponFeignService.membercoupons();
Object coupons = membercoupons.get("coupons");
return R.ok()
.put("member", memberEntity)
.put("coupons", coupons);
}
}

此时调用接口即可

image-20240119160350012

Nacos配置中心

导入依赖到common模块:

        <!--        配置中心来做配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

在coupon模块下面创建一个bootstrap.yml文件,bootstrap文件会优先于application文件:

spring:
application:
name: gulimall-coupon

cloud:
nacos:
config:
server-addr: localhost:8848

测试配置coupon模块:

application.properties创建一个配置文件:

coupon.user.name="cxk"
coupon.user.age=18

写一个测试接口用来获取:

@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
@Value("${coupon.user.name}")
private String name;
@Value("${coupon.user.age}")
private Integer age;
@RequestMapping("/test")
public R test() {
return R.ok().put("name", name).put("age", age);
}
}

此时发送请求可以获取到值。

现在有新的需求,希望修改值之后可以实时看到结果,步骤如下:

在配置列表中创建配置:

image-20240119165127974

写入以下内容:

image-20240119165213261

在控制器上面加注解RefreshScope:

@RestController
@RequestMapping("coupon/coupon")
@RefreshScope
public class CouponController {

此时nacos中的配置重新发布即可。如果配置中心和配置文件配置相同的项,优先使用配置中心的配置。

使用细节:

  1. 命名空间:
  • 默认为public,用来做配置隔离,可以自己创建命名空间,如dev,test等

  • image-20240119171023665

  • 此时需要在bootstrap文件中配置namespace 命名空间id:

    spring:
    application:
    name: gulimall-coupon

    cloud:
    nacos:
    config:
    server-addr: localhost:8848
    namespace: 12e5ed93-2be2-44c0-93d4-4cdc0a65426e

    1. 配置集:所有配置文件的集合
    2. 配置集ID:类似文件名 Data ID:类似文件名
    3. 配置分组: 默认DEFAULT_GROUP

Gateway网关

官方文档:https://docs.spring.io/spring-cloud-gateway/docs/3.0.8/reference/html/#gateway-starter

创建一个网关模块:

添加common模块依赖,以及gateway依赖:

		<dependency>
<groupId>com.cxk</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

开启nacos注册发现:

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableDiscoveryClient
public class GulimallGatewayApplication {

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

测试配置路由规则:

spring:
cloud:
gateway:
routes:
- id: test_route
uri: https://www.baidu.com
predicates:
- Query=url, baidu

- id: qq_route
uri: https://www.qq.com
predicates:
- Query=url, qq

此时可以访问:http://localhost:88?url=qq. -> qq.com

http://localhost:88?url=baidu