电商项目——初识电商——第一章——上篇
电商项目——分布式基础概念和电商项目微服务架构图,划分图的详解——第二章——上篇
电商项目——电商项目的虚拟机环境搭建_VirtualBox,Vagrant——第三章——上篇
电商项目——Linux虚拟机中安装docker,mysql,redis_VirtualBox——第四章——上篇
电商项目——电商项目的环境搭建_开发工具&环境搭建——第五章——上篇
电商项目——快速开发人人开源搭建后台管理系统&代码生成器逆向工程搭建——第六章——上篇
电商项目——分布式组件(SpringCloud Alibaba,SpringCloud)——第七章——上篇
电商项目——前端基础——第八章——上篇
电商项目——商品服务-API-三级分类——第九章——上篇
电商项目——商品服务-API-品牌管理——第十章——上篇
电商项目——商品服务-API-属性分组——第十一章——上篇
电商项目——商品服务-API-品牌管理——第十二章——上篇
电商项目——商品服务-API-平台属性——第十三章——上篇
电商项目——商品服务-API-新增商品——第十四章——上篇
电商项目——商品服务-API-商品管理——第十五章——上篇
电商项目——商品服务-API-仓库管理——第十六章——上篇
讲述前六章的内容以后,有了一定的积淀,我们就可以开始搭建分布式系统的基本环境
在分布式开发中,我们要先知道微服务-注册中心,配置中心,网关三个概念
SpringCloud Alibaba官方文档
Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用
微服务的必需组件,方便开发者通过Spring Cloud 编程横型轻松使用这些组件来开发分布
式应用服务。
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将Spring Cloud应用。接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
https://github.com/alibaba/spring-cloud-alibaba
SpringCloud 的几大痛点
SpringCloud 部分组件停止维护和更新。给开发者来不便;
SpringCloud部扮环境搭建复杂,没有完善的可视化界面,我们需要大量的二次开发和定制
SpringCloud配置复杂。难以上手,部分配置差别难以区分和合理应用
阿里使用过的组件经历了考验,性能强悍,设计合理,现在开源出来大家用
成套的产品搭配完善的可视化界面给开发运维蒂来极大的便利
搭建简单,学习曲线低
SpringCloud Allbaba-Nacos:注册中心(服务发现/注册)
SpringCloud Alibaba- Nacos.配置中心(动态配置管理)
SpringCloud-Ribbon:负载均衡
SpringCloud- Feign.声明式HTP客户端(调用远程服务)
SpringCloud Alibaba- Sentinel:服务容错(限流、降级、熔断)
SpringCloud- Gateway. API网关(webflux编程模式)
Springcloud-Sleuth:调用链监控
SpringCloud Alibaba-Seata:原Fescar,即分布式事务解决方案
第一步:注意版本
第二步:在mall-common中引入如下依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>2.1.0.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
我们先了解一下Spring Cloud应用如何接入Nacos Discovery
在mall-common中引入如下的配置
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
application:
name: mall-coupon
示例,在mall-coupon中开启服务注册于发现功能
@EnableDiscoveryClient
@MapperScan("com.atstudying.mall.coupon.dao")
@SpringBootApplication
public class MallCouponApplication {
public static void main(String[] args) {
SpringApplication.run(MallCouponApplication.class, args);
}
}
第一步:去nacos中打开bin,点击startup执行
要在mall-coupon中配置application name,以便Nacos的可视化界面可以找到微服务的服务名
spring:
application:
name: mall-coupon
小例子:mall-member微服务调用mall-coupon服务,比如会员想要从优惠劵中获取优惠的信息,就要进行远程调用
在mall-member中引入Open Feign
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
声明远程式接口,告诉SpringCloud这个接口需要调用远程服务,声明接口的每一个方法调用的是哪个远程服务的那个请求
mall-member
//声明了一个CouponFeignService 远程式接口,声明接口的memberCoupom方法调用的是mall-coupon 中的/coupon/coupon/member/list
@FeignClient("mall-coupon")
public interface CouponFeignService {
@RequestMapping("/coupon/coupon/member/list")
public R memberCoupom();
}
mall-coupon中编写一个方法供mall-member调用
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
@Autowired
private CouponService couponService;
@RequestMapping("/member/list")
public R memberCoupom(){
CouponEntity couponEntity=new CouponEntity();
couponEntity.setCouponName("zlj");
couponEntity.setCouponType(2);
return R.ok().put("ok",Arrays.asList(couponEntity));
}
@EnableFeignClients(basePackages = "com.atstudying.mall.member.Feign.CouponFeignService")
@EnableDiscoveryClient
@SpringBootApplication
public class MallMemberApplication {
public static void main(String[] args) {
SpringApplication.run(MallMemberApplication.class, args);
}
}
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-nacos-configartifactId>
dependency>
在mall-coupon中演示
bootstrap.properties会优先于application.properties加载
例子证明:
application.properties
coupon.user.name=zlj
coupon.user.age=20
提示:如果直接user.name=zlj,浏览器不会给你zlj,而是你系统变量的名字,为了区分开来,我们要写上前缀,比如coupon
测试:
http://localhost:20000/coupon/coupon/test
{"msg":"success","code":0,"name":"zlj","age":"20"}
我们在配置一个bootstrap.properties
配置如下两个文件
spring.application.name=mall-coupon
spring.cloud.nacos.config.server-name=localhost:8848
Nacos配置中心
mall-coupon.properties
coupon:
user:
name:zhangsan
age: 22
http://localhost:20000/coupon/coupon/test
{"msg":"success","code":0,"name":"name:zhangsan","age":"22"}
完成上述两步后,应用会从Nacos Config中获取相应的配置,并添加在Spring Environment的PropertySources中。这里我们使用@Value注解来将对应的配置注入到CouponController 的userName和age字段。井添加@RefreshScope打开动态刷新功能
@RestController
@RefreshScope
@RequestMapping("coupon/coupon")
public class CouponController {
@Autowired
private CouponService couponService;
@Value("${coupon.user.name}")
private String name;
@Value("${coupon.user.age}")
private String age;
//测试nacos config
@RequestMapping("/test")
public R test(){
return R.ok().put("name",name).put("age",age);
}
(1)开发,测试,生产,利用命名空间来做环境隔离。
注意。在bootstrap. propertiesi配置上,需要使用哪个命名空间下的配置
spring.cloud.nacos.config.namespace=3dc59cad-5171-42a2-9e56-eb7b69c5f790
(2).每一个微服务之间互相隔高配置。每一个微服务都创建自己的命名空间。只加载自己命名空间下的所有配置
默认所有的配置集 都属于,DEFAULT GROUP:
每个微服务创建自的命名空间,使用配置分组区分环境,dev, test. prod
mall-coupon
bootstrap.properties
spring.application.name=mall-coupon
spring.cloud.nacos.config.server-addr=192.168.232.1:8848
spring.cloud.nacos.config.namespace=56551c3c-d75a-41ea-8b72-349326b483c9
#spring.cloud.nacos.config.group=
spring.cloud.nacos.config.ext-config[0].dataId=datasource.yml
spring.cloud.nacos.config.ext-config[0].group=dev
spring.cloud.nacos.config.ext-config[0].refresh=true
spring.cloud.nacos.config.ext-config[1].dataId=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].dataId=Nacos.yml
spring.cloud.nacos.config.ext-config[2].group=dev
spring.cloud.nacos.config.ext-config[2].refresh=true
spring.cloud.nacos.config.ext-config[3].dataId=test1.properties
spring.cloud.nacos.config.ext-config[3].group=test
spring.cloud.nacos.config.ext-config[3].refresh=true
进行测试
@RestController
@RefreshScope
@RequestMapping("coupon/coupon")
public class CouponController {
@Autowired
private CouponService couponService;
@Value("${coupon.user.name}")
private String name;
@Value("${coupon.user.age}")
private String age;
//测试nacos config
@RequestMapping("/test")
public R test(){
return R.ok().put("name",name).put("age",age);
}
{"msg":"success","code":0,"name":"test","age":"18"}
更改nacos中心的配置,可以完成自动修改
{"msg":"success","code":0,"name":"testchange","age":"18"}
网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制等。而spingcloud gateway网关作为SpringCloud官方推出的第二代网关框架,取代了Zuul网关。
网上测试对比结果
SpringCloud Gateway的三个术语
路由:网关的基本构件。它由一个ID、一个目标URI、一个谓词集合和一个过滤器集合定义。如果聚合谓词为真,则匹配路
断言:这是一个Java 8函数谓词。输入类型是Spring Framework ServerWebExchange。这使我们可以匹配来自HTTP请求的任何内容,例如头或参数。
Filter:这些是Spring Framework GatewayFilter的实例,使用特定的工厂构造。在这里,我们可以在发送下游请求之前或之后修改请求和响应。
构建于Spring Framework 5、Project Reactor和Spring Boot 2.0之上
能够匹配任何请求属性上的路由。
谓词和过滤器是特定于路由的。
Hystrix断路器集成。
Spring Cloud发现客户端集成
易于编写谓词和过滤器
请求速率限制
路径重写
我们要引入mall-common依赖,因为网关既要注册中心也要配置中心,都在mall-common中有配置,还要引入网关依赖
//....
com.atstudying.mall
mall
0.0.1-SNAPSHOT
org.springframework.cloud
spring-cloud-starter-gateway
spring.application.name=mall-gateway
spring.cloud.nacos.config.server-addr=localhost:8848
spring.cloud.nacos.config.namespace=3787d0b6-aedf-458e-996a-714234a7fe55
spring.cloud.nacos.config.ext-config[0].dataId=basic.yaml
spring.cloud.nacos.config.ext-config[0].group=dev
spring.cloud.nacos.config.ext-config[0].refresh=true
spring.cloud.nacos.config.ext-config[1].dataId=gateway.yaml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true
@EnableDiscoveryClient
@SpringBootApplication
public class MallGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(MallGatewayApplication.class, args);
}
}
gateway.yaml
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://www.baidu.com
predicates:
- Path=/qq/**,/wechat/**
因为我们的mall-gateway整合了mall-common的所有依赖,可是网关不需要配置数据源(不需要网关的mybatis,有了就会报错)
com.baomidou
mybatis-plus-boot-starter
两种解决方法:
<dependency>
<groupId>com.atstudying.mallgroupId>
<artifactId>mall-commonartifactId>
<version>0.0.1-SNAPSHOTversion>
<exclusions>
<exclusion>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
exclusion>
exclusions>
dependency>
@EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class MallGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(MallGatewayApplication.class, args);
}
}