一、springcloudalibaba介绍
微服务简介
微服务是一种软件架构风格,它将一个大型应用程序拆分成一组更小、独立的服务,每个服务都可以独立开发、部署和扩展。每个服务都有自己的业务逻辑和数据库,并且通过轻量级通信机制(如RESTful
API)来相互通信。
微服务架构的优点包括
- 可扩展性:由于每个服务都是独立的,因此可以根据需要对其进行扩展,而不会影响整个应用程序
- 独立部署:每个服务都可以单独部署,因此可以更快地推出新功能和修复错误。
- 松耦合:每个服务都是独立的,因此可以使用不同的技术栈和语言,无需担心与其他服务的兼容性问题。
- 更好的可维护性:由于每个服务都是独立的,因此可以更轻松地维护和更新它们。
微服务架构也存在一些挑战
- 分布式系统的复杂性:由于微服务架构涉及多个独立的服务,因此必须处理分布式系统的复杂性和挑战。
- 部署和监控的复杂性:每个服务都需要单独部署和监控,这可能会增加管理和维护的难度。
- 数据一致性的挑战:由于每个服务都有自己的数据库,因此必须处理数据一致性的问题。
尽管存在这些挑战,微服务架构仍然是越来越受欢迎的软件架构风格,因为它可以帮助企业更快地开发和部署应用程序,并提供更好的可扩展性和可维护性。
SpringCloudAlibaba
Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。 此项目包含开发分布式应用微服务的必需组件,方便开发者通过
Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务
为什么要使用SpringCloudAlibaba
由于SpringCloud有些组件不在提供维护,所以现在基本都是在用SpringCloudAlibaba
Spring Cloud Alibaba 是基于 Spring Cloud 的一套开发框架,提供了一系列的解决方案,可以帮助开发者快速构建分布式应用程序。它具有以下优点:
集成了众多阿里巴巴开源产品,如 Nacos、Sentinel、Dubbo 等,可以轻松实现服务注册和发现、服务治理、流量控制等功能。
提供了丰富的组件和工具,如 Spring Cloud Alibaba Stream、Spring Cloud Alibaba Bus 等,可以简化开发者的编码工作。
它具有高可用性、高可扩展性、高性能等特点,可以满足企业级应用的需求。
它是开源的,可以免费使用,并且社区活跃,可以获得及时的技术支持和更新。
综上所述,使用 Spring Cloud Alibaba 可以使开发者更加轻松地构建分布式应用程序,提高开发效率和应用性能,因此得到了越来越多开发者的青睐。
二、环境配置
nacos介绍
Nacos是一个开源的动态服务发现、配置管理和服务管理平台,由阿里巴巴集团开源。它提供了一种简单易用的方式来管理云原生应用的动态配置和服务发现,支持多种数据格式(如JSON、XML、YAML等),支持多种语言(如java、Go、Python等),并且具有高可用、可扩展、易于部署等特点。
Nacos的主要功能包括:
-
服务发现和注册:Nacos提供了一个服务注册中心,可以让服务提供者将自己的服务注册到中心,让服务消费者可以通过中心来发现和调用服务。
-
配置管理:Nacos提供了一个统一的配置中心,可以让应用程序动态地获取配置信息,支持配置的动态发布和变更。
-
服务管理:Nacos提供了一个服务管理平台,可以让用户管理服务的生命周期,包括服务的上线、下线、健康状态等。
Nacos的优点包括:
-
功能全面:Nacos提供了服务发现、配置管理和服务管理等多种功能,可以满足云原生应用的各种需求。
-
易于使用:Nacos提供了简单易用的API和UI界面,可以让用户快速上手。
-
高可用性:Nacos支持集群部署,可以保证高可用性和可扩展性。
-
生态丰富:Nacos与Spring Cloud、Dubbo等主流微服务框架集成良好,可以方便地与其他微服务组件进行集成。
总之,Nacos是一个功能全面、易于使用、高可用性、生态丰富的动态服务发现、配置管理和服务管理平台,是云原生应用开发的重要组件之一。
nacos下载地址
https://github.***/alibaba/nacos/releases
这里我使用的是2.0.3
下载完成后进行解压
启动nacos
因为我们在本地写项目,也一般用不到集群,所以nacos启动我们设置为单机模式(standalone)
首先是这四个文件
startup 是用于启动nacos服务的,可以看到有两个文件,一个是cmd用于windows系统启动,一个是sh,shell脚本,用于linux上启动
shutdown是用于停止nacos服务的,两个文件同上
第一种方法
进入bin目录,打开cmd执行
startup.cmd -m standalone
第二种
更改nacos启动文件
将cluster更改为standalone设置为单机模式,然后保存退出,点击startup.cmd即可启动nacos服务
可以看到这样就启动服务成功了,并且是单机模式
访问nacos
http://localhost:8848/nacos/#/login
因为我是在本地配置的nacos,所以地址就是本地的地址localhost(http://127.0.0.1/),如果你们是在虚拟机上配置的,这个需要改成你虚拟机的ip地址
在服务管理中的服务列表,就可以看到你注册到nacos的服务
三、项目搭建
首先创建一个springboot项目用于主项目
springboot版本可自行选择,反正我感觉不要太低,也不要太高
下面是选择依赖,这里不选择,直接点击Finish,依赖我们进去自己配置
创建完成后就是一个普通的springboot项目,但是可能有时候会出现依赖报错的问题
依赖报错问题解决方案
- 首先去检查网络,是否正常
- 网络没问题的话就打开ideal左上角的File - Settings - Build, Execution, Deployment - Build Tools - Maven
查看这里是不是你的本地Maven仓库 - 这里如果也没问题,还是报错的话,就去检查你的settings.xml是否配置了阿里镜像或者华为镜像,因为他默认的是从国外获取依赖
配置阿里云镜像或者华为镜像
- 配置后还是不行,参考
删除依赖,重新进行下载,因为可能有网络原因,他下载没有下载完整
- 其实终究于是网络,以上方法都不行,建议换个网络!!
回到创建完springboot项目后
删除没必要的包
可以看到上图,他的项目结构,因为我们不在主项目也就是父项目里写代码,所以要删除没用的包
留下这四个就行
创建子项目
右键项目 - New - Module
我们选择Maven项目,next
Finish
创建完成后看你的Maven
可以看到鼠标选择的地方后边出现了一个root,他也就是主项目,service就是他的子项目
然后重复上部操作,创建***mon子项目,gateway子项目
然后介绍一下这三个子项目的作用
-
service
首先service就是用于放子子项目的,也就是我们的服务,举个例子(存放用户服务,订单服务),一个服务也是一个项目, -
***mon
这个可以理解为,公共服务,我们用到的一些util类,包括实体类等,还用于一些公共依赖,例如sql,
mybtis,lombok等,其他服务通过依赖的方式去导入它 -
gateway
首先说一下gateway是什么
Spring Cloud Alibaba Gateway是一种基于Spring Cloud Gateway实现的API网关,它提供了一些额外的功能,如动态路由、限流、熔断、安全认证等。它可以作为微服务架构中的入口,将所有的请求统一转发到后端的微服务中,并提供了一些通用的功能,如请求转发、请求过滤、请求重试等。同时,它还支持多种协议,如HTTP、WebSocket、TCP等。Spring Cloud Alibaba Gateway是一个非常强大的工具,可以帮助开发者快速构建高可用、高性能的微服务架构。
简单理解可以理解为,它就是一个在消费者和提供者中间的一个城门,消费者都去访问它,它通过配置的规则去转发请求到对应的服务里
具体配置一会再配置
最后就是这样的一个样子
也可以看到主项目的pom文件
导入依赖
主项目依赖
现在往主项目里导入依赖
将这三个依赖删除
将依赖替换成
<!--pom版本控制,通过dependencyManagement完成继承-->
<dependencyManagement>
<dependencies>
<!-- springboot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- alibaba -->
<dependency>
<groupId>***.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.7.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
***mon依赖
<dependencies>
<!-- 统一排除logback日志包的冲突 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- SpringWeb启动依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Boot热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- Mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!-- 发送邮箱验证码-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- SpringBoot集成Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- SpringBoot集成Rabbitmq Starter 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- 阿里巴巴OSS对象存储 -->
<dependency>
<groupId>***.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.***/artifact/***.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>***.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!-- 代码生成器 -->
<dependency>
<groupId>***.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
<!-- https://mvnrepository.***/artifact/org.apache.velocity/velocity-engine-core -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
<!-- 打印日志 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- JSON字符串处理 -->
<dependency>
<groupId>***.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<!-- https://mvnrepository.***/artifact/***.auth0/java-jwt -->
<dependency>
<groupId>***.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.18.2</version>
</dependency>
<!-- 汉字转拼音 -->
<dependency>
<groupId>***.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.0</version>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.http***ponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.1</version>
</dependency>
<!--***mons-io-->
<dependency>
<groupId>***mons-io</groupId>
<artifactId>***mons-io</artifactId>
<version>2.6</version>
</dependency>
<!--gson-->
<dependency>
<groupId>***.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<!-- Hutool工具包-->
<dependency>
<groupId>***.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.3</version>
</dependency>
<!-- naCos 服务注册发现(客户端)依赖 -->
<dependency>
<groupId>***.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 导入依赖OpenFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 使用Apache HttpClient替换Feign原生httpclient -->
<!-- feign-httpclient内含Apache HttpClient -->
<!-- https://mvnrepository.***/artifact/io.github.openfeign/feign-httpclient -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
</dependencies>
gateway依赖
<dependencies>
<!-- Boot热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- nacos 服务注册发现(客户端)依赖 -->
<dependency>
<groupId>***.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba整合Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- SpringCloud Alibaba整合Sentinel -->
<dependency>
<groupId>***.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>***.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
</dependencies>
service依赖
直接使用***mon的公共依赖,如果单独需要,那么就在有需求的服务里导入依赖
这个groupId记得要改,是你自己起的包名
<dependencies>
<!-- 使用公共项目 -->
<dependency>
<groupId>***.fyj</groupId>
<artifactId>***mon</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
新建service子项目服务,并注册到nacos中
因为service子项目也不写代码,所以src文件夹可以删掉
方法同刚才一样,只不过是有些需要改的,到下图这个页面,改成service
创建用户(user)服务和order(订单)服务,子项目会继承父项目的所有依赖,自己看一下Maven就知道了
配置***mon
其实上面也讲了,就是放一些公共的东西,可以去我的项目里复制,或者你自己配置也行。
代码生成器生成服务中的代码
在生成前,先创建表
user表和order表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT ***MENT '主键',
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL ***MENT '用户名',
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL ***MENT '用户密码',
`age` int NULL DEFAULT NULL ***MENT '年龄',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '小明', '123213123', 18);
SET FOREIGN_KEY_CHECKS = 1;
DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (
`id` int NOT NULL AUTO_INCREMENT ***MENT '主键',
`user_id` int NULL DEFAULT NULL ***MENT '用户ID',
`order_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL ***MENT '订单编号',
`order_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL ***MENT '订单名称',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of order
-- ----------------------------
INSERT INTO `order` VALUES (1, 1, 'xaw-2004-0926', '订单001');
INSERT INTO `order` VALUES (2, 1, 'xaw-2001-0926', '订单002');
SET FOREIGN_KEY_CHECKS = 1;
然后连接数据库,生成代码
package utils;
import ***.baomidou.mybatisplus.core.mapper.BaseMapper;
import ***.baomidou.mybatisplus.generator.FastAutoGenerator;
import ***.baomidou.mybatisplus.generator.config.OutputFile;
import java.util.Collections;
/**
* 代码生成器
* @Author: beisheng,
* Date: 2022/6/18 15:01,
* Version: IntelliJ IDEA 2021.2.1
*
*/
public class Generator {
public static void main(String[] args) {
generate();
}
private static void generate(){
FastAutoGenerator.create("jdbc:mysql://8.143.205.127/sa_salary?serverTimezone=Asia/Shanghai&useUnicode=true&" +
"characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true",
"root", "Zqw123456")
.globalConfig(builder -> {
builder.author("beisheng") // 设置作者
// .enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.***mentDate("yyyy-MM-dd")
.outputDir("D:\\项目文件\\凌云\\薪想事成\\Salary\\service\\salary\\src\\main\\java\\***\\buba\\"); // 指定输出目录 *
})
.packageConfig(builder -> {
builder.parent("") // 设置父包名 !!!
.moduleName("") // 设置父包模块名
.mapper("mapper")
.xml("mapper")
.pathInfo(Collections.singletonMap(OutputFile.xml,
"D:\\项目文件\\凌云\\薪想事成\\Salary\\service\\salary\\src\\main\\resources\\mapper\\")); // 设置mapperXml生成路径 !!!
})
.strategyConfig(builder -> {
builder.addInclude("payrolls") // 设置需要生成的表名 !!!
.addTablePrefix("", "_table")// 设置过滤表前缀 !!!
.serviceBuilder() //service生成策略
.formatServiceFileName("%sService") //service类名,%s适配,根据表明替换
.formatServiceImplFileName("%sServiceImpl") // service实现类
.entityBuilder() //实体类生成策略
.enableLombok() //开启lombok
// .logicDeleteColumnName("deleted) //说明逻辑删除是哪个字段
.enableTableFieldAnnotation() // 属性加上说明注解
.controllerBuilder() //controller生成策略
.enableHyphenStyle() //开启驼峰转连字符
.formatFileName("%sController")
.enableRestStyle() //开启RestController
.mapperBuilder()
.superClass(BaseMapper.class) //dao层继承父类
.formatMapperFileName("%sMapper")
// .enableMapperAnnotation() //@Mapper注解开启
.formatXmlFileName("%sMapper");
})
// .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
模板可以去项目里复制
执行main方法,生成代码
生成完后把实体类放到***mon里去,因为各个服务可能会出现调用
配置启动类以及配置文件
user
application.yml
server:
port: 8003
servlet:
context-path: /user
spring:
#配置服务名及nacos
application:
name: user
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
alibaba:
seata:
tx-service-group: my_test_tx_group
# 数据源 config
datasource:
driver-class-name: ***.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/txt?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: root
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
#Redis配置
redis:
host: 127.0.0.1
port: 6379
jedis:
pool:
max-active: 8
max-wait: -1ms
max-idle: 500
min-idle: 0
lettuce:
shutdown-timeout: 0ms
# password: root
servlet:
multipart:
max-file-size: 500MB #单个数据大小
max-request-size: 1024MB #总数据大小
mybatis-plus:
#mapper配置文件 扫描所有* xml文件
mapper-locations: classpath*:mapper/**/*.xml
configuration:
auto-mapping-behavior: full
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印sql语句
#指定包的别名
type-aliases-package: ***.fyj.*
logging:
level:
#需要开启日志打印,为防止过多冗余日志。可以指定我们feign的接口。
***.bgs.feign: debug
feign:
client:
config:
#指定服务名
nacos-producer:
loggerLevel: FULL
httpclient:
# 为feign启用 apache httpclient 做请求,而不使用默认的urlconection
enabled: true
# feign 最大连接数
max-connections: 200
# feign 单个路径请求的最大连接数
max-connections-per-route: 50
启动类:
package ***.fyj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class userApplication {
public static void main(String[] args) {
SpringApplication.run(userApplication.class,args);
}
}
启动user服务
order
yml
server:
port: 8002
servlet:
context-path: /order
spring:
#配置服务名及nacos
application:
name: order
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# 数据源 config
datasource:
driver-class-name: ***.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/txt?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: root
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
#Redis配置
redis:
host: 127.0.0.1
port: 6379
jedis:
pool:
max-active: 8
max-wait: -1ms
max-idle: 500
min-idle: 0
lettuce:
shutdown-timeout: 0ms
# password: root
servlet:
multipart:
max-file-size: 500MB #单个数据大小
max-request-size: 1024MB #总数据大小
mybatis-plus:
#mapper配置文件 扫描所有* xml文件
mapper-locations: classpath*:mapper/**/*.xml
configuration:
auto-mapping-behavior: full
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印sql语句
#指定包的别名
type-aliases-package: ***.fyj.*
logging:
level:
#需要开启日志打印,为防止过多冗余日志。可以指定我们feign的接口。
***.bgs.feign: debug
feign:
client:
config:
#指定服务名
nacos-producer:
loggerLevel: FULL
httpclient:
# 为feign启用 apache httpclient 做请求,而不使用默认的urlconection
enabled: true
# feign 最大连接数
max-connections: 200
# feign 单个路径请求的最大连接数
max-connections-per-route: 50
启动类
package ***.fyj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient//服务注册发现
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
}
在nacos的服务列表里就可以看到两个启动的服务
接下来写一个单服务的全查,进行访问
postman测试
这里出了一个问题
因为order好像是关键字,他会报错,改一下名字,实体类也要改
改完后就测试成功了
但是通常前端都是把请求封装起来成一个js,端口号是不变的,所以我们配置gateway进行请求的转发
gateway配置
# 项目入口,可以使用80,也可以随意
server:
port: 8090
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
sentinel:
transport:
# 添加sentinel的控制台地址
dashboard: 127.0.0.1:8861
gateway:
globalcors: # 跨域配置
cors-configurations:
'[/**]':
allow-credentials: true #允许携带认证信息Cookie
# 我们可以通 过域名的方式 也可以通过指定ip 还可以 allowed-origins: "*" #放行所有跨域请求
allowed-origins: "*"
allowed-headers: "*" #允许所有请求头
allowed-methods: "*" #允许所有请求方式
max-age: 86400 # 86400 秒,也就是 24 小时 在有效时间内,浏览器无须为同一请求再次发起预检请求,可以减少发送请求的次数,减少系统部分压力。
routes:
# 路由id,可以任意写,但是要保证唯一
# “-”:代表为list,可以配置多个
- id: user
# 代理的服务地址(将匹配到的url路由到代理地址上)
# uri: http://localhost:8050
# 代理的服务地址(将匹配到的url路由到代理地址上) feign-consummer nacos服务名
uri: lb://user
# 谓词: url要匹配的规则,如果匹配成功则路由到上面的uri上。
predicates:
- Path=/user/**
# 路由id,可以任意写,但是要保证唯一
# “-”:代表为list,可以配置多个
- id: order
# 代理的服务地址(将匹配到的url路由到代理地址上)
# uri: http://localhost:8050
# 代理的服务地址(将匹配到的url路由到代理地址上) feign-consummer nacos服务名
uri: lb://order
# 谓词: url要匹配的规则,如果匹配成功则路由到上面的uri上。
predicates:
- Path=/order/**
logging:
level:
org.springframework.cloud.gateway: debug
配置启动类以及解决跨域配置
package ***.buba.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
/**
* @Author: beisheng
* @Date: 2022/9/29 11:40
*/
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsWebFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
configuration.addAllowedOrigin("*");
// 是否允许携带cookie跨域
configuration.setAllowCredentials(true);
source.registerCorsConfiguration("/**", configuration);
return new CorsWebFilter(source);
}
}
将gateway也注册到nacos中
package ***.fyj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class, args);
}
}
测试把端口号改成gateway的端口号,可以发现也能访问
openFeign
定义
OpenFeign是Spring Cloud Alibaba中的一个组件,它是一个声明式的Web服务客户端,可以让开发者更加方便地调用HTTP API。
OpenFeign的使用方式类似于Spring MVC中的注解方式,开发者只需要定义一个接口,然后使用注解来描述这个接口需要调用的HTTP API,OpenFeign就会自动根据这些注解生成一个实现了这个接口的代理对象。这个代理对象可以像调用本地方法一样调用远程的HTTP API。
OpenFeign还提供了一些其他的功能,比如负载均衡、熔断器、请求重试等。这些功能可以让开发者更加方便地构建高可用、高可靠的分布式系统。
总之,Spring Cloud Alibaba OpenFeign是一个非常方便的工具,可以让开发者更加轻松地调用HTTP API,同时也提供了一些其他的功能,可以帮助开发者构建高可用、高可靠的分布式系统。
代码
现在有个需求
用户服务需要根据用户ID去查询当前用户的订单,所以需要用户服务去调用订单服务,使用springcloudalibaba的openFeign去调用其他服务
- 首先在user服务启动类上加一个注解@EnableFeignClients 开启feign调用
- 在order服务上写一个根据用户ID查询的单查方法
/* *
* @Author: beisheng
* @Descriprion: 根据用户ID查询订单
* @Date: 2023/5/12 17:06
* @Return: ***mon.R
* @Param: [id]
*/
@GetMapping("/selOrderByUserId")
public List<Orders> selOrderByUserId(@RequestBody Integer id){
List<Orders> users = orderService.list(new QueryWrapper<Orders>().eq("user_id", id));
return users;
}
- user服务新建一个文件夹为feign,并新建一个接口orderfeign
代码
package ***.fyj.feign;
import entity.order.Orders;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@FeignClient(name = "order",path = "/order")
public interface orderFeign {
/* *
* @Author: beisheng
* @Descriprion: 根据用户ID查询订单
* @Date: 2023/5/12 17:06
* @Return: ***mon.R
* @Param: [id]
*/
@GetMapping("/selOrderByUserId")
List<Orders> selOrderByUserId(@RequestBody Integer id);
}
在user服务上调用
package ***.fyj.controller;
import ***.fyj.feign.orderFeign;
import ***mon.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 前端控制器
* </p>
*
* @author yixin
* @since 2023-05-12
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private orderFeign orderFeign;
@GetMapping("zzz")
public R zzz(){
return R.su***ess(orderFeign.selOrderByUserId(1));
}
}
重启两个服务
测试
结果已经出来了
四 、总结
中间我也遇到了一些问题,可能在上面没有优化好,有什么问题可以问
现在就是用到了springCloudAlibaba的nacos,gateway,以及openFeign
后面可能还会去继续完善,例如nacos配置中心,服务熔断,消息中间件等