Spring Cloud Alibaba商城实战项目(day02)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

四、搭建Spring Cloud Alibaba环境

4.1、简介

官方文档https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/zh-cn/index.html

image-20230105192310592

我们所选用的组件

  1. SpringCloud Alibaba - Nacos注册中心服务发现/注册

  2. SpringCloud Alibaba - Nacos配置中心动态配置管理

  3. SpringCloud - Ribbon负载均衡

  4. SpringCloud - Feign声明式 HTTP 客户端调用远程服务

  5. SpringCloud Alibaba - Sentinel服务容错限流、降级、熔断

  6. SpringCloud - GatewayAPI 网关webflux 编程模式

  7. SpringCloud - Sleuth调用链监控

  8. SpringCloud Alibaba - Seata原 Fescar即分布式事务解决方案

4.2、注册服务Nacos

Nacos 使用三步

  1. 导包 nacos-discovery。
  2. 写配置指定 nacos 地址指定应用的名字。
  3. 开启服务注册发现功能@EnableDiscoveryClient。

由于以后项目的依赖都有SpringCloud Alibaba所以我们把依赖直接全部加到mall-common中。我们先加入一个版本管理。

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

引入我们选好的组件的依赖即可。

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

    </dependencies>

接着去下载nacos-server用于服务注册和发现。我们去官网下载nacos-server的压缩包。官网地址https://github.com/alibaba/nacos/releases。下载完以后进入bin目录可以直接运行startup.cmd即可启动nacos-server。

image-20230105194721657

image-20230105194829337

运行成功。

如果想要使用nacos-server我们还需要配置nacos的地址。

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

在启动类上加一个注解表示允许开启服务发现。

package cn.linstudy.coupon;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
// 允许服务发现注解
@EnableDiscoveryClient
public class MallCouponApplication {

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

}

配置成功后我们就可以通过http://127.0.0.1:8848/nacos/访问nacos可视化中心账号密码都是nacos。

image-20230105212142974

可以发现服务已经注册上去了这个服务名称就是我们这行配置的。

spring:
  application:
    name: mall-coupon

接下来我们依葫芦画瓢把其他服务也注册上去。

image-20230105212818390

大功告成

4.3、远程调用Feign

Feign 使用三步

  1. 导包 openfeign
  2. 开启@EnableFeignClients功能
  3. 编写接口进行远程调用

4.3.1、简介

Feign 是一个声明式的 HTTP 客户端它的目的就是让远程调用更加简单。Feign 提供了HTTP请求的模板通过编写简单的接口和插入注解就可以定义好 HTTP 请求的参数、格式、地址等信息。 Feign 整合了 Ribbon负载均衡和 Hystrix(服务熔断)可以让我们不再需要显式地使用这两个组件。 SpringCloudFeign 在 NetflixFeign 的基础上扩展了对 SpringMVC 注解的支持在其实现下我们只需创建一个接口并用注解的方式来配置它即可完成对服务提供方的接口绑定。简化了SpringCloudRibbon 自行封装服务调用客户端的开发量。

4.3.2、加入openfeign

首先先导入依赖。

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <!--要记得加版本号否则会报错-->
            <version>2.2.6.RELEASE</version>
        </dependency>

其次在启动类上写一个注解开启openfeign。

package cn.linstudy.coupon;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
// 允许服务发现注解
@EnableDiscoveryClient
// 允许远程调用注解
@EnableFeignClients
public class MallCouponApplication {

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

}

4.3.3、测试

调用远程服务的步骤

  1. 引入open-feign。
  2. 编写一个接口告诉springcloud这个接口需要调用哪个远程服务。
  3. 声明接口的每一个方法都是调用哪个远程服务的哪个请求。
  4. 开启远程远程调用功能。在basePackages属性中书写远程调用包所在地方。

写一个优惠券的类去测试。

    // 测试openfrign
    @RequestMapping("test")
    public R memberCoupon(){
        CouponEntity couponEntity = new CouponEntity();
        couponEntity.setCouponName("俺是优惠券");
        return R.ok().put("coupons", Arrays.asList(couponEntity));
    }

我们通过mall-member服务来远程调用mall-coupon服务。CouponFeignService会先去nacos找mall-coupon这个服务再去找/coupon/coupon/test接口的方法。那么项目启动后就会去扫描feign下的对应的方法。

package cn.linstudy.member.feign;

import cn.linstudy.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

// 告诉客户端我是远程调用客户端
@FeignClient("mall-coupon")
public interface CouponFeignService {

    // 把需要调用的方法签名复制一份即可
    @RequestMapping("/coupon/coupon/test")
    R memberCoupon();
}

最后在MemberController中写一个测试类即可。

    private CouponFeignService couponFeignService;
    @RequestMapping("/coupons")
    public R getCoupons(){
        R r = couponFeignService.memberCoupon();
        return R.ok().put("coupons",r.get("coupons"));
    }

直接浏览器访问http://localhost:8000/member/member/coupons

image-20230105232311963

大功告成

4.4、配置中心Nacos Config

当然Ncacos也可以作为配置中心好处是修改了配置无需重启项目把配置交给nocaos统一管理首先需要引入依赖。直接CV丢到mall-common中。

<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

Spring Cloud Alibaba在/src/main/resources下创建一个bootstrap.properties来s配置文件中配置 Nacos Config 元数据。来配置两个属性

  1. spring.application.name应用名字一般用模块名来命名。
  2. spring.cloud.nacos.config.server-addrnacos地址。
spring.application.name=mall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

然后启动nacos将一些配置全部迁移到nacos中。

image-20230106105503268

将mall-coupon中的配置从yaml转到properties并添加到nacos配置中发布即可。

image-20230106105755188

4.4.1、概念

4.4.1.1、命名空间

命名空间用于进行租户粒度的配置隔离。不同的命名空间下可以存在相同的Group 或Data ID的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离例如开发测试环境和生产环境的资源如配置、服务隔离等。

4.4.1.2、配置集

一组相关或者不相关的配置项的集合称为配置集。在系统中一个配置文件通常就是一个配置集包含了系统各个方面的配置。例如一个配置集可能包含了数据源、线程池、日志级别等配置项。

4.4.1.3、配置集 ID

Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包如 com.taobao.tc.refund.log.level的命名规则保证全局唯一性。此命名规则非强制。

4.4.1.4、配置分组

Nacos 中的一组配置集是组织配置的维度之一。通过一个有意义的字符串如Buy 或Trade 对配置集进行分组从而区分 Data ID 相同的配置集。当您在Nacos 上创建一个配置时如果未填写配置分组的名称则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景不同的应用或组件使用了相同的配置类型如database_url 配置和MQ_topic 配置。

4.4.2、项目整合Nacos Config

如果我们把所有的配置都写在一个配置文件中会显得配置文件很臃肿且不好维护所以我们根据不同的功能来分开写。这个项目我们根据服务来隔离配置首先先新建一个coupon优惠券命名空间。

image-20230106115225007

接着迁移mybatis-plus相关配置。

image-20230106115332147

将其他相关配置迁移就完成了。

image-20230106115454504

最后需要在bootstrap.properties中配置读取多个配置文件。

#读取哪个配置文件
spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml
#读取哪个环境
spring.cloud.nacos.config.extension-configs[0].group=dev
#是否需要自动刷新
spring.cloud.nacos.config.extension-configs[0].refresh=true

#读取哪个配置文件
spring.cloud.nacos.config.extension-configs[1].data-id=mybatis-plus.yml
#读取哪个环境
spring.cloud.nacos.config.extension-configs[1].group=dev
#是否需要自动刷新
spring.cloud.nacos.config.extension-configs[1].refresh=true

#读取哪个配置文件
spring.cloud.nacos.config.extension-configs[2].data-id=other.yml
#读取哪个环境
spring.cloud.nacos.config.extension-configs[2].group=dev
#是否需要自动刷新
spring.cloud.nacos.config.extension-configs[2].refresh=true

启动完发现端口还是配置好的7000且没有报错目前是成果配置了。

image-20230106120254095

4.4.3、原理

4.4.3.1、自动注入

NacosConfigStarter 实现了 org.springframework.cloud.bootstrap.config.PropertySourceLocator 接口并将优先级设置成了最高。 在 Spring Cloud 应用启动阶段会主动从 Nacos Server 端获取对应的数据并将获取到的数据转换成 PropertySource 且注入到 Environment 的 PropertySources 属性中所以使用@Value 注解也能直接获取 Nacos Server 端配置的内容。

4.4.3.2、动态刷新

Nacos Config Starter 默认为所有获取数据成功的 Nacos 的配置项添加了监听功能在监听到服务端配置发生变化时会实时触发 org.springframework.cloud.context.refresh.ContextRefresher 的 refresh 方法。如果需要对 Bean 进行动态刷新请参照 Spring 和 Spring Cloud 规范。推荐给类添加@RefreshScope 或 @ConfigurationProperties 注解

4.5、网关Gateway

网关作为流量的入口常用功能包括路由转发、权限校验、限流控制等。而springcloud gateway作为 SpringCloud 官方推出的第二代网关框架取代了 Zuul 网关。网关提供 API 全托管服务丰富的 API 管理功能辅助企业管理大规模的API以降低管理成本和安全风险包括协议适配、协议转发、安全策略、防刷、流量、监控日志等功能。Spring Cloud Gateway 旨在提供一种简单而有效的方式来对 API 进行路由并为他们提供切面例如安全性监控/指标 和弹性等。 官方文档地址 https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.3.RELEASE/single/spring-cloud-gateway.html

Spring Cloud Gateway 特点:

  1. 基于 Spring5支持响应式编程和 SpringBoot2.0。
  2. 支持使用任何请求属性进行路由匹配。
  3. 特定于路由的断言和过滤器。
  4. 集成 Hystrix 进行断路保护。
  5. 集成服务发现功能。
  6. 易于编写 Predicates 和 Filters。
  7. 支持请求速率限制。
  8. 支持路径重写。

4.5.1、整合网关

我们首先先创建一个网关服务同时网关服务也是需要交给nacos管理所以也需要配置nacos相关配置包括写注解配置和告知网关服务nacos的地址。

cloud:
  nacos:
    discovery:
      server-addr: 127.0.0.1:8848
spring:
  application:
    name: mall-gateway
server:
  port: 88

在启动类上加一个注解。

package cn.linstudy.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class MallGatewayApplication {

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

}

引入依赖后就可以开始测试了。

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

启动后会出现这个错误。

image-20230106213605044

因为我们是网关层不需要数据源相关配置所以我们直接把他排除掉即可。在启动类上注解里面排除即可。

@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})

一启动就会有惊喜

image-20230106230932888

image-20230106230943230

这里会遇到一个bug由于gateway与springboot-web会有冲突我们需要把他排除掉但是我们不可以在父项目中排除因为其他的项目还需要用到所以我们需要在引入mall-common的地方排除掉springboot-web。

<dependency>
            <groupId>cn.linstudy</groupId>
            <artifactId>mall-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

image-20230106231134907

大功告成

4.5.2、测试

在application.yml中可以书写网关规则。

spring:
  cloud:
    gateway:
      routes:
#          路由规则名称
        - id: test_route
          uri: https://www.baidu.com
#          断言Query=url表示如果有url这个参数且url的值等于baidu就跳到这个url
          predicates:
            - Query=url,baidu
        #          路由规则名称
        - id: qq_route
          uri: https://www.qq.com
          #          断言Query=url表示如果有url这个参数且url的值等于qq就跳到这个url
          predicates:
            - Query=url,qq

启动后输入

image-20230106182148456.png

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring