文章目录
一、SpringCloud Alibaba
1、SpringCloud Alibaba简介
1)、简介
Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。 此项目包含开发分布式应用微服务的必需组件,方便开发者通过Spring Cloud编程模型轻松便用这些组件来开发分布式应用服务。
依托Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将SpringCloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
官网地址:https://github.com/alibaba/spring-cloud-alibaba
Github中文文档说明:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
主要功能:
- 服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
- 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
- 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
- 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
- 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。。
- 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
- 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
组件:
- Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
- Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
- RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
- Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。
- Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
- Alibaba Cloud OSS:阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
- Alibaba Cloud SchedulerX:阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。
- Alibaba Cloud SMS:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
2)、为什么使用
SpringCloud的几大痛点:
- SpringCloud部分组件停止维护和更新,给开发带来不便;
- SpringCloud部分环境搭建复杂,没有完善的可视化界面,我们需要大量的二次开发和定制
- SpringCloud配置复杂,难以上手,部分配置差别难以区分和合理应用
SpringCloud Alibaba的优势:
- 阿里使用过的组件经历了考验,性能强悍,设计合理,现在开源出来大家用
- 成套的产品搭配完善的可视化界面给开发运维带来极大的便利
- 搭建简单,学习曲线低。
结合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、SpringCloud Alibaba-Nacos 下载与安装
Nacos是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。他是使用java编写。需要依赖java环境。
Nacos文档地址:https://nacos.io/zh-cn/docs/quick-start.html
官网文档说明:https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html
Nacos就是注册中心 + 配置中心的组合 等价于 Nacos = Eureka + config + Bus
1)、下载nacos-server
https://github.com/alibaba/nacos/releases
2)、启动
- 双击bin中的 startup.cmd 文件
- 访问
http://localhost:8848/nacos/
- 使用默认的nacos/nacos进行登录
3、Nacos【作为注册中心】
1. 引入 Nacos Discovery Starter依赖
<!--spring cloud alibaba 2.1.0.RELEASE-->
<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>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2. 配置文件中配置 Nacos Server 地址
server.port=8081
spring.application.name=nacos-provider
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
management.endpoints.web.exposure.include=*
注意:每一个应用都应该有名字,这样才能注册上去,修改application.properties文件。
3. 在主启动类中开启服务注册与发现功能
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
4. 消费者业务
@RestController
@Slf4j
public class OrderNacosController {
/*
因为在yml中配置了service-url.nacos-user-service,
这里不需要再定义要访问微服务名常量,而是通过boot直接读出来
*/
@Value("${service-url.nacos-user-service}")
private String serverURL;
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Long id){
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
}
}
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //RestTemplate结合Ribbon做负载均衡一定要加@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
Nacos支持AP和CP模式的切换
5. 注册更多的服务上去,测试使用 feign 远程调用
Nacos使用三步:
1、导包 nacos-discovery
2、写配置,指定nacos地址,指定应用的名字
3、开启服务注册发现功能@EnableDiscoveryClient
Fegin使用三步:
1、导包 openfegin
2、开启@EnableFeginClients
功能
3、编写接口,进行远程调用
4、Nacos【作为配置中心】
1、pom.xml 引入Nacos Config Starter
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2、在应用的 /src/main/resources/bootstrap.properties 配置文件
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=43e4b62f-d65b-4295-bf06-8be264de464b
spring.cloud.nacos.config.group=prod
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
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
3、在nacos中添加配置
Nacos界面配置对应:
公式:${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file.extension}
- prefix默认为spring.application.name的值
- spring.profile.active即为当前环境对应的profile,可以通过配置项 spring.profile.active来配置。
- file.extension为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file.extension来配置
4、在应用中使用@Value 和@RefreshScope
5、进阶
1、核心概念
- 命名空间:
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的Group 或Data ID 的配置。Namespace的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。 - 配置集:
一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置。例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。 - 配置集ID:
Nacos中的某个配置集的ID。 配置集ID是组织划分配置的维度之一。Data lD通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。DataID 通常采用类Java 包(com.taobao.tc.refund.loglevel) 的命名规则保证全局唯一性。此命名规则非强制。
4、SpringCloud Alibaba-Sentinel
5、SpringCloud Alibaba-Seata
6、SpringCloud Alibaba-OSS
1、简介
对象存储服务(Object Storage Seryice,OSS)是一种海量、安全、低成本、高可靠的云存储服务,适合存放任意类型的文件。容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本。
2、图示说明
- 文件存储
- 阿里云对象存储-普通上传方式
- 阿里云对象存储-服务端签名后直传
3、资源术语
中文 | 英文 | 说明 |
---|---|---|
存储空间 | Bucket | 存储空间是您用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间。 |
对象/文件 | Object | 对象是 OSS 存储数据的基本单元,也被称为OSS的文件。 对象由元信息(Object Meta)、用户数据(Data)和文件名(Key)组成。对象由存储空间内部唯一的Key来标识。 |
地域 | Region | 地域表示 OSS 的数据中心所在物理位置。您可以根据费用、 请求来源等综合选择数据存储的地域。详情请查看OSS已经开通的Region。 |
访问域名 | Endpoint | Endpoint 表示OSS对外服务的访问域名。OSS以HTTP RESTful API的形式对外提供服务, 当访问不同地域的时候,需要不同的域名。通过内网和外网访问同一个地域所需要的域名也是不同的。 具体的内容请参见各个Region对应的Endpoint。 |
访问密钥 | AccessKey | AccessKey,简称 AK,指的是访问身份验证中用到的AccessKeyId 和AccessKeySecret。 OSS通过使用AccessKeyId 和AccessKeySecret对称加密的方法来验证某个请求的发送者身份。 AccessKeyId用于标识用户,AccessKeySecret是用户用于加密签名字符串和OSS用来验证签名字符串的密钥, 其中AccessKeySecret 必须保密。 |
4、使用步骤
1、开通 “对象存储OSS”服务
(1)打开阿里云网站 https://www.aliyun.com/
(2)注册阿里云账户,最好使用支付宝,需要实名认证
(3)使用注册的用户登录阿里云里面
(4)找到阿里云oss
(5)开通oss
没开通的这里是开通过oss,我这里是已经开通好了,所以显示管理控制台。
(6)文档位置
快速入门文档:https://help.aliyun.com/document_detail/32011.html?spm=a2c4g.11186623.6.905.23866328891B4P
2、进入oss管理控制台
(1)使用oss,首先创建bucket
创建说明:
其他的使用默认就好。
(2)控制台上传图片
这里我们为了测试手动上传张图片。
3、Java代码操作阿里云oss上传文件
1、准备工作:创建操作阿里云oss许可证(阿里云颁发id和秘钥)
整个阿里云有个账号和密码,我们可以基于这个账号下开通好多子账户,所以选择开始使用子用户AccessKey。
这里我们需要先开通RAM
选择用户,创建用户
此时列表中就有刚创建的用户,点进去就可以看到 AccessKey ID
和 AccessKeySecret
默认刚添加的用户没有任何权限,所以我们点击添加权限,我们选择管理对象存储服务权限
2、结合Java代码实现简单上传文件案例
(1)POM
<!--aliyunOSS-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.5.0</version>
</dependency>
(2)测试创建Bucket的连接
public class OSSTest {
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 上传文件流。
InputStream inputStream = new FileInputStream("<yourlocalFile>");
ossClient.putObject("<yourBucketName>", "<yourObjectName>", inputStream);
// 关闭OSSClient。
ossClient.shutdown();
}
5、项目中使用OSS步骤
这里我将OSS服务 使用在微服务项目(SpringBoot+SpringCloud)中
(1)创建 gulimall-third-party
模块
(2)POM.xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>
(3)将oss相关参数配置在配置文件中方便使用
spring:
cloud:
alicloud:
access-key: LTAI4Fzsbs1syidddhfQaF
secret-key: HI5sZsLdzVyGGOuddddoHlj2Ddubla
oss:
endpoint: oss-cn-beijing.aliyuncs.com
bucket: gulimall-hello
server:
port: 30000
(4)使用官网提供的代码
官网地址:https://help.aliyun.com/document_detail/31926.html?spm=a2c4g.11186623.6.1718.30e94c07sh9tqa
选择Java版本。
@RestController
public class OssController {
@Autowired
OSS ossClient;
@Value("${spring.cloud.alicloud.oss.endpoint}")
private String endpoint;
@Value("${spring.cloud.alicloud.oss.bucket}")
private String bucket;
@Value("${spring.cloud.alicloud.access-key}")
private String accessId;
@RequestMapping("/oss/policy")
public R policy() {
//https://gulimall-hello.oss-cn-beijing.aliyuncs.com/hahaha.jpg
String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
// callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
// String callbackUrl = "http://88.88.88.88:8888";
String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String dir = format + "/"; // 用户上传文件时指定的前缀。
Map<String, String> respMap = null;
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = ossClient.calculatePostSignature(postPolicy);
respMap = new LinkedHashMap<String, String>();
respMap.put("accessid", accessId);
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", dir);
respMap.put("host", host);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
// respMap.put("expire", formatISO8601Date(expiration));
} catch (Exception e) {
// Assert.fail(e.getMessage());
System.out.println(e.getMessage());
}
return R.ok().put("data",respMap);
}
}
这里我把代码写在Controller中方便调用,并且根据项目返回的是R对象(这里看自己项目需求)
(5)启动项目访问http://localhost:30000/oss/policy
在整合前端项目时候,会报如下错误:意思是我们本项目向阿里云访问的时候出现跨域问题。
解决:在阿里云创建的oss服务中开启跨域访问
二、SpringCloud
1、Feign声明式远程调用
1、简介
Feign是一个声明式的HTTP客户端,它的目的就是让远程调用更加简单。Feign 提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。
Feign整合了Ribbon(负载均衡)和Hystrix(服务熔断),可以让我们不再需要显式地使用这两个组件。
SpringCloudFeign 在 NetflixFeign 的基础上扩展了对SpringMVC注解的支持,在其实现下,我们只需创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定。简化了SpringCloudRibbon自行封装服务调用客户端的开发量。
2、使用
1)、引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、声明远程接口
@FeignClient("gulimall-coupon")
public interface CouponFeginService {
@RequestMapping("/coupon/coupon/member/list")
public R membercoupons();
}
3、开启fegin功能
@EnableFeignClients(basePackages = "com.kuang.gulimall.member.fegin")
2、Gateway
1、概念
网关作为流量的入口,常用功能包括路由转发权限校验、限流控制等。而springcloud gateway作为SpringCloud官方推出的第二代网关框架,取代了Zuul 网关。
2、使用
1)、引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2、添加@EnableDiscoveryClient注解
/**
* 1、开启服务注册发现
* (配置nacos服务注册中心地址)
*/
@EnableDiscoveryClient
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class})
public class GulimallGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallGatewayApplication.class, args);
}
}
3、在 /src/main/resources/application.properties 配置文件
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.application.name=gulimall-gateway
server.port=88
4、在 /src/main/resources/application.yml 配置文件
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
- id: product_route
uri: lb://gulimall-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{
segment}
- id: third_party_route
uri: lb://gulimall-third-party
predicates:
- Path=/api/thirdparty/**
filters:
- RewritePath=/api/thirdparty/(?<segment>.*),/$\{
segment}
- id: member_route
uri: lb://gulimall-member
predicates:
- Path=/api/member/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{
segment}
- id: ware_route
uri: lb://gulimall-ware
predicates:
- Path=/api/ware/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{
segment}
- id: admin_route
uri: lb://renren-fast
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*),/renren-fast/$\{
segment}
5、在 /src/main/resources/bootstrap.properties 配置文件
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=bffa6312-559a-4c6f-aaea-0ab468a2e684
6、启动“gulimall-gateway”
启动报错:
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
解决方法:在“io.niceseason.gulimall.gulimallgateway.GulimallGatewayApplication”中排除和数据源相关的配置
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class})
重新启动
访问:http://192.168.137.14:8848/nacos,查看到该服务已经注册到了Nacos中