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

Posted 钱难有~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud Alibaba商城实战项目(day02)相关的知识,希望对你有一定的参考价值。

四、搭建Spring Cloud Alibaba环境

4.1、简介

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

我们所选用的组件:

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

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

  3. SpringCloud - Ribbon:负载均衡

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

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

  6. SpringCloud - Gateway:API 网关(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。

运行成功。

如果想要使用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。

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

spring:
  application:
    name: mall-coupon

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

大功告成!

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

大功告成!

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-addr:nacos地址。
spring.application.name=mall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

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

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

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优惠券命名空间。

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

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

最后需要在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且没有报错,目前是成果配置了。

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>

启动后会出现这个错误。

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

@SpringBootApplication(exclude= DataSourceAutoConfiguration.class)

一启动,就会有惊喜!

这里会遇到一个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>

大功告成!

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

启动后输入

以上是关于Spring Cloud Alibaba商城实战项目(day02)的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud Alibaba商城实战项目基础篇(day01)

Spring Cloud Alibaba商城实战项目基础篇(day03)

Spring Cloud Alibaba商城实战项目基础篇(day03)

五分钟带你玩转spring cloud alibaba越玩越溜!实战Spring Cloud Alibaba Sentinel

五分钟带你玩转spring cloud alibaba越玩越溜!实战Spring Cloud Alibaba Sentinel

springcloud 微服务Spring Cloud Alibaba 整合Nacos实战