Day397.SpringCloud Alibaba -谷粒商城

Posted 阿昌喜欢吃黄桃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day397.SpringCloud Alibaba -谷粒商城相关的知识,希望对你有一定的参考价值。

SpringCloud Alibaba

一、项目依赖

0、组件

https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md

1、项目技术选择

结合 SpringCloud Alibaba 这里使用的技术搭配方案:

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

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

SpringCloud - Ribbon :负载均衡

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

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

SpringCloud - Gateway :API 网关(webflux 编程模式)

SpringCloud - Sleuth :调用链监控

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


2、版本选择

所以阿昌这里选择如下版本

  • SpringBoot:

    • 2.4.1
  • SpringCloud Alibaba:

    • 2.2.0.RELEASE

achangmall-common的pom.xml中加入:

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

在别的服务模块的pom.xml中将springboot的版本修改为

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

二、SpringCloud Alibaba-Nacos

Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。他是使用 java 编写。需要依赖 java 环境

Nacos 文档地址https://nacos.io/zh-cn/docs/quick-start.html

1、下载 nacos-server

https://github.com/alibaba/nacos/releases

以下win版本为例

2、启动 nacos-server

  • 双击 bin 中的 startup.cmd 文件
  • 访问 http://localhost:8848/nacos/
  • 使用默认的 nacos/nacos 进行登录

如果出现nacos is starting with cluster

可以尝试使用cmd命令行去指定使用单体模式启动,如下:

startup.cmd -m standalone

3、将微服务注册到 nacos 中

  • 首先,修改achangmall-common中的pom.xml 文件,引入 Nacos Discovery Starter 依赖。
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  • 在应用的common中的application.yml 配置文件中配置 Nacos Server 地址微服务名称

如下举个例子,把现在所有的服务都加入如下配置,让他注册到nacos中

spring:
  datasource:
    password: root
    username: root
    url: jdbc:mysql://192.168.109.101:3306/achangmall_sms?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.jdbc.Driver

  application:
    name: achangmall-coupon #对应微服务名
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #nacos地址

在每个服务的主入口上标注注解@EnableDiscoveryClient(现在默认不需要标注)

@SpringBootApplication
@MapperScan("com.achang.achangmall.coupon.dao")
@EnableDiscoveryClient //标注启动服务发现
public class AchangmallCouponApplication {
    public static void main(String[] args) {
        SpringApplication.run(AchangmallCouponApplication.class, args);
    }
}

再刷新nacos,查看,发现服务已经注册进nacos了!!!


4、测试member和coupon的远程调用

想要获取当前会员领取到的所有优惠券。先去注册中心找优惠券服务, 注册中心调一台优惠券服务器给会员,会员服务器发送请求给这台优 惠券服务器,然后对方响应。

在调用方的主函数头上标注注解打开远程调用,并指定包位置

//开启远程调用,并指定包位置
@EnableFeignClients(basePackages = "com.achang.achangmall.member.feign")
@SpringBootApplication
@MapperScan("com.achang.achangmall.member.dao")
public class AchangmallMemberApplication {
    public static void main(String[] args) {
        SpringApplication.run(AchangmallMemberApplication.class, args);
    }
}

coupon服务中被调用接口

/**
     * 当前用户所有优惠劵
     */
@RequestMapping("/member/list")
public R memberCoupon(){
    CouponEntity couponEntity = new CouponEntity();
    couponEntity.setCouponName("满一百减10");
    return R.ok().put("list",Arrays.asList(couponEntity));
}

member服务中创建feign包,并在下面创建CouponFeignService;

@FeignClient("achangmall-coupon") //标注要调用的服务名
public interface CouponFeignService {
    final String headUrl = "/coupon/coupon";
    
    //指定要调用上面指定服务的那个接口
    @GetMapping(headUrl+"/member/list") 
    public R memberCoupon();
}

然后阿昌这里启动member服务,报了No Feign Client for loadBalancing defined.Did you forget to include spring-cloud-starter-loadbalance错误

解决方案

在achangmall-common中修改并引入依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    <version>2.2.1.RELEASE</version>
</dependency>

在member服务中添加测试接口,测试远程调用

@RestController
@RequestMapping("member/member")
public class MemberController {
    @Autowired
    private CouponFeignService couponFeignService;

    @GetMapping("/test")
    public R test(){
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setNickname("阿昌");

        //远程调用
        R r = couponFeignService.memberCoupon();
        return R.ok().put("member",memberEntity).put("coupon",r.get("list"));
    }
    
    //省略别的接口.........
}

重启member服务,并访问:http://localhost:8000/member/member/test,调用成功!


5、配置中心

我们还可以用nacos作为配置中心。配置中心的意思是不在application.properties 等文件中配置了,而是放到nacos配置中心公用,这样无需每台机器都改。

https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md-----官方文档

  • 引入配置中心依赖,放到common中
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  • 在coupons项目中创建/src/main/resources/bootstrap.properties ,这个文件是 springboot里规定的,他优先级别application.properties高
# application.properties
coupon.name=achang
coupon.age=18


# bootstrap.properties
#springboot里规定的,bootstrap.properties的优先级比application.properties高
# 改名字,对应nacos里的配置文件名
spring.application.name=achangmall-coupon
spring.cloud.nacos.config.server-addr=localhost:8848
  • 测试配置文件获取
@Value("${coupon.name}")
private String name;

@Value("${coupon.age}")
private Integer age;

@GetMapping("/test")
public R test(){
    return R.ok().put("name",name).put("age",age);
}

  • 在nacos中发布配置

  • 在Controller加上@RefreshScope来动态获取配置数据

这里阿昌遇到了问题:

发现我项目里配置的bootstarp.properties不生效,所以就无法知道远程配置中心的内容;

这里缺少了依赖,因为我使用的是2020以上的版本

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
    <version>3.0.3</version>
</dependency>

具体的maven仓库:

https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap

  • 动态修改配置中心的配置如下:

  • 测试再访问http://localhost:7000/coupon/coupon/test,动态刷新配置成功


6、配置中心进阶

  • 命名空间

用作配置隔离。(一般每个微服务一个命名空间)

在nacos中创建对应的名称空间

在创建对应配置文件中指定对于的名称空间

通过spring.cloud.nacos.config.namespace在指定使用哪个名称空间

spring.cloud.nacos.config.namespace=ed042b3b-b7f3-4734-bdcb-0c516cb357d7  # 可以选择对应的命名空间 ,即写上对应环境的命名空间ID
  • 配置集ID

类似于配置文件名,即Data ID

  • 配置分组

默认所有的配置集都属于DEFAULT_GROUP。自己可以创建分组,比如双十一,618,双十二

最终方案:每个微服务创建自己的命名空间,然后使用配置分组区分环境(dev/test/prod)

spring.cloud.nacos.config.group=DEFAULT_GROUP  # 更改配置分组
  • 加载多配置集

将一个配置文件,抽取成多个配置文件

bootstrap.properties

#服务名
spring.application.name=achangmall-coupon 
#配置中心地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

 #可以选择对应的命名空间 ,即写上对应环境的命名空间ID
spring.cloud.nacos.config.namespace=ed042b3b-b7f3-4734-bdcb-0c516cb357d7
# 配置文件所在的组
spring.cloud.nacos.config.group=dev  

#加载多配置集
#数据源配置
spring.cloud.nacos.config.ext-config[0].data-id=datasource.yml
spring.cloud.nacos.config.ext-config[0].group=dev
spring.cloud.nacos.config.ext-config[0].refresh=true

#mybaits配置
spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true

#其他配置
spring.cloud.nacos.config.ext-config[2].data-id=other.yml
spring.cloud.nacos.config.ext-config[2].group=dev
spring.cloud.nacos.config.ext-config[2].refresh=true

7、GateWay网关

网关是请求浏览的入口,常用功能包括路由转发,权限校验,限流控制等。springcloud gateway取到了zuul网关。

  • 发送请求需要知道商品服务的地址,如果商品服务器有100服务器,1号掉线后, 还得改所以需要网关动态地管理,他能从注册中心中实时地感知某个服务上 线还是下线。

  • 请求也要加上询问权限,看用户有没有权限访问这个请求,也需要网关。

  • 三大核心概念:

    • Route:
      • 发一个请求给网关,网关要将请求路由到指定的服务。路由有id,目的地uri,断言的集合,匹配了断言就能到达指定位置,
    • Predicate
      • java里的断言函数,匹配请求里的任何信息,包括请求头等
    • Filter
      • 过滤器请求和响应都可以被修改。
  • 客户端发请求给服务端。中间有网关。先交给映射器,如果能处理就交给handler 处理,然后交给一系列filer,然后给指定的服务,再返回回来给客户端。

  • 流程图

  • 创建模块achangmall-gateway

  • 在pom.xml引入
<dependency>
    <groupId>com.achang.achangmall</groupId>
    <artifactId>achangmall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
  • 开启注册服务发现@EnableDiscoveryClient
//不自动装配数据源
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableDiscoveryClient //开启注册服务发现
public class AchangmallGatewayApplication {
	public static void main(String[] args) {
		SpringApplication.run(AchangmallGatewayApplication.class, args);
	}
}
  • 配置nacos注册中心地址applicaion.properties
spring.application.name=achangmall-gateway
spring.cloud.nacos.discovery.server-addr=localhost:8848
server.port=88
  • bootstrap.properties 填写配置中心地址
spring.application.name=achangmall-gateway
spring.cloud.nacos.config.server-addr=localhost:8848
spring.cloud.nacos.config.namespace=d4b1e29c-de65-47fb-9817-334099a69352
  • nacos里创建命名空间gateway,然后在命名空间里创建文件achangmall-gateway.yml
spring:
  cloud:
    gateway:
      routes:
        - id: baidu_route
          uri: http://www.baidu.com
          predicates:
            - Query=url,baidu

        - id: test_route
          uri: http://www.qq.com
          predicates:
            - Query=url,qq
  • 测试

http://localhost:88/?url=qq

http://localhost:88/?url=baidu


以上是关于Day397.SpringCloud Alibaba -谷粒商城的主要内容,如果未能解决你的问题,请参考以下文章

01.Spring Cloud Alibab简介及初始环境搭建

spring cloud 与 spring boot 和 spring cloud alibab 版本号对应

spring cloud alibab nacos:nacos作为注册中心如何使用

各种json报错

java图片缩放与裁剪

BizCharts 双坐标轴: