媒介
这是尚硅谷2024Cloud教程的笔记,只是记录学习历程,方便自己以后查询。周阳老师讲的很好,给出原视频地址
对应1.Boot和Cloud选项,2.Cloud组件的停更,升级,更换,3.Base工程构建。
1.Boot和Cloud选项
1.JDK
SpringBoot3.0开始,对于JDK的最低版本是JDK17,逼迫要求,从JDK8.x 到JDK17的变化。又因OracleJDK的协议,推荐使用OpenJDK。OpenJDK官网下载。在语法层面和OracleJDK没有区别,只是Oracle在OpenJDK上,加了一些额外的商业特性。一样平常使用,OpenJDK可以了。
2.Maven
Spring官网,对于SpringBoot3.0+的maven版本要求是3.6.3+。注意该组件的版本,会影响idea的版本,因为较高的Maven,在idea2021某个版本之前的版本无法使用,亲身踩坑/(ㄒoㄒ)/~~。可以使用3.6.3,对各个版本的boot和idea兼容新都不错。推荐,使用Maven3.6.3,但是为和老师,保持同等,故使用3.9.5。
3.MySQL
MySQL8.x版本,推出于2018年,距今已有较长时间。在稳定性,社区活跃度等方面都不错,以及免费的特性,实际项目开辟中有较多使用。
备注:Spring官网,查看框架底子的依赖组件的版本要求
选择一个版本的Boot,查看Reference Doc,其中的Getting Started中的System Requirements有本版本下,对于jdk,maven,tomcat最低的版本要求。
因为,要选择差别的jdk,差别的maven,所以需要这些信息。乃至,高版本的maven还需要和更高版本的idea适配。
4.技能选项问题
如果是新项目,直接上微服务,是Cloud版本决定,Boot版本。旧项目改造,是Boot版本决定Cloud版本,因为整体项目从boot2.7.x,升级到3.x的代价还是比较高的。在Spring官网,中有Cloud和与Boot的版本依赖关系。官网地址
5.本次课程先容
5.1 上篇
SpringCloud
5.2 下篇
SpringCloud Alibaba
5.3 说明
SpringCloud和SpringCloud Alibaba相互独立,都是微服务头脑的具体实现的产物,雷同点就是Spring官方,将Alibaba纳入到了其维护的项目中,不外alibaba也在维护,且alibaba版本会更快。因为毕竟是自己的产物,之后才会同步到Spring社区。
6.SpringBoot版本选择
6.1 GitHub地址
https://github.com/spring-projects/spring-boot/releases
6.2 官网看Boot版本
6.3 SpringBoot3.0的崛起
Spring Boot 3.0 requires Java 17 as a minimum version. SpringBoot3.0对于JDK的最低版本要求是JDK17。
7.SpringCloud版本选择
7.1 github地址
https://github.com/spring-cloud
7.2 官网看Cloud版本
7.2.1 Cloud定名规则
SpringCloud的版本关系
Spring Cloud 接纳了英国伦敦地铁站的名称来定名,并由地铁站名称字母A-Z依次类推的形式来发布迭代版本
SpringCloud是一个由许多子项目组成的综合项目,各子项目有差别的发布节奏。为了管理SpringCloud与各子项目的版本依赖关系,发布了一个清单,其中包括了某个SpringCloud版本对应的子项目版本。为了避免SpringCloud版本号与子项目版本号肴杂,SpringCloud版本接纳了名称而非版本号的定名,这些版本的名字接纳了伦敦地铁站的名字,根据字母表的顺序来对应版本时间顺序。例如Angel是第一个版本, Brixton是第二个版本。
当SpringCloud的发布内容积聚到临界点或者一个庞大BUG被解决后,会发布一个"service releases"版本,简称SRX版本,好比Greenwich.SR2就是SpringCloud发布的Greenwich版本的第2个SRX版本。
但是从2020年开始,以2020.0.x的方式定名版本,解决了,令人无法明白的版本定名。
7.2.2 官网地址
https://spring.io/projects/spring-cloud
8.SpringCloud Alibaba版本选择
8.1 SpringCloud官网
https://spring.io/projects/spring-cloud-alibaba
注意,此方式无法看到最新版。有延后。
8.2 Spring Cloud Alibaba官网GitHub说明
和老师保持同等,选择2020.x。
8.3 SpringCloudAlibaba版本
https://github.com/alibaba/spring-cloud-alibaba/releases
本次视频定稿
框架间的版本适配,请严格依照官网,或者GitHub。
SpringCloud和SpringBoot和SpringCloud Alibaba三者,制约关系。是Cloud版本决定,Boot版本。
下图是SpringCloudAlibaba - SpringCloud - SpringBoot的版本关系。
结论
底子组件版本JDKJava17+Maven3.9+MySQL8.0+Spring Cloud2023.0.0Spring Boot3.2.0Spring Cloud Alibaba2022.0.0.0-RC22.Cloud组件的听更,升级,更换
1.微服务理论知识入门
1.1 形象一点来说
微服务架构就像搭积木,每个微服务都是一个零件一个积木,并使用这些积木零件组装出差别的外形,出来最后一个完备的物体。
1.2 通俗来说
微服务架构就是把一个大系统按业务功能分解成多个职责单一的小系统,每一个小模块尽量埋头的只做一件事,并利用简朴的方法使多个小系统相互协作,组成一个大系统再统一对外提供整体服务。
1.3 学科派一点
专注一单一责任小型功能模块为底子,并利用轻量化机制(通常为HTTP RESTFUL API)实现通信完成复杂业务搭建的一种架构头脑。
2.Spring Cloud是什么?
方便程序员专注于业务逻辑的,由分布式头脑落地的框架和一些中间件“有机联合”的产物。
3.本次解说的内容-粗略版
4.本次解说的内容-详推版
4.1 2018第一季
4.2 Netflix OSS被移除的原因
Netflix OSS(Open Source System),是Netflix公司开辟的一套代码框架和库,SpringCloud Netflix是在Netflix OSS底子之上的封装。
更新版本没有什么大惊小怪的,但是本次更新却正式开启了Spring Cloud Netflix体系的终结历程。Netflix公司是目前微服务落地中最乐成的公司。它开源了诸如Eureka、Hystrix、Zuul、Feign、Ribbon等等广大开辟者所知微服务套件,统称为Netflix OSS。在当时 Netflix OSS成为微服务组件上究竟的尺度。但是微服务鼓起不久,也就是在2018年前后Netflix公司公布其核心组件Eureka、Hystrix、Zuul、Feign、Ribbon等进入维护状态,不再进行新特性开辟,只修BUG。
这直接影响了Spring Cloud项目的发展路线,Spring官方不得不采取了应对措施,在2019年的在SpringOne2019大会中,Spring Cloud公布 Spring Cloud Netflix项目进入维护模式,并在2020年移除相关的Netflix OSS组件。
4.2.1 Netflix那些被移除了?
2019年进入Maintenance Mode。
维护模式,就是被动的修复bugs,不再接收合并请求,不再发布新版本。换句话说就是,除非出现特别严峻的bug,否则没人管了。
4.2.2 由停更引发的“升级惨案”
红叉:不能再使用了;感叹号:能用但是不推荐;对号:推荐使用。
备注,remove的组件都不能使用。
3.Base工程构建
1.订单->支付,业务需求说明
2.约定>设置>编码
约定,业内基本达成共识的一些想法,好比在Web开辟中,Post请求,往往用来添加数据,Get请求,用来获取数据,Delete请求,用来删除数据等。
设置,是提前确定好,使用的组件的版本信息,因为版本辩论的问题,导致的设置,是让人特别厌恶和反感的。这也是一般微服务项目,都会有一个公共的父模块,在这个父模块的pom文件中,定义好使用的各种框架,组建的版本。各个子模块,在自己的pom文件中,使用定义好的版本的依赖。
编码,就是写代码。
3.IDEA新建Project和Maven父工程
3.1 微服务cloud整体聚合Maven父工程
3.1.1 New Project
略,注意,创建父工程时,不要使用Spring的初始化工具,创建Maven项目。
3.1.2 定义父工程名字
- <groupId>com.atguigu.cloud</groupId>
- <artifactId>cloud</artifactId>
- <version>1.0-SNAPSHOT</version>
复制代码 3.1.3 定义字符编码
File -> Settings -> Editor -> File Encodings
设置Global Encoding,Project Encoding,Default encoding for properties files 都为UTF-8,以及勾选Transparent native-to-ascii conversion。
3.1.4 注解生效激活
File -> Settings -> Build,Execution,Deployment -> Complier -> Annotation Processors
Enable annotation processing勾选。
3.1.5 Java编译版本选17
File -> Settings -> Build,Execution,Deployment -> Complier -> Java Complie
Target bytecode version选择17
3.1.6 File Type过滤
File -> Settings -> Editor -> File Types
Ignored FIles and Folders
添加*.idea文件
小结
以上设置,都可以设置在新创建项目中,也就是说新建的项目,会主动使用,设置好的。
File -> New Project Setup -> Settings for New Projects
3.2 父工程POM文件内容
这也是父工程存在的意义,提前定义好,本系统中,可能会使用的依赖的版本,防止,因版本辩论问题出现bug。注意,这里实际不引入jar包,只是定义版本。3.3.Maven工程细节复习
Maven中的dependencyManagement和dependencies。
Maven 使用dependencyManagement元素来提供了一种管理依赖版本号的方式。
通常会在一个组织或者项目的最顶层的父POM 中看到dependencyManagement元素。
使用pom.xml 中的dependencyManagement元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用这个dependencyManagemen元素中指定的版本号。
如许做的利益就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,优势:
- 1.如许当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改 ;
- 2.别的如果某个子项目需要别的的一个版本,只需要声明version就可。
dependencyManagement里只是声明依,并不实现引入,因此子项目需要显示的声明需要用的依赖。
如果不在子项目中声明依赖,是不会从父项目中继承下来的,只有在子项目中写了该依赖项并且没有指定具体版本,才会从父项目中继承该项 且version和scope都读取自父pom;
如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
Maven中跳过单元测试
1.设置- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
- </build>
复制代码 2.IDEA工具支持(推荐)
3.4 MySQL驱动说明
3.4.1 MySQL 5.7
- # mysql5.7---JDBC四件套
- jdbc.driverClass = com.mysql.jdbc.Driver
- jdbc.url= jdbc:mysql://localhost:3306/db2024?useUnicode=true&characterEncoding=UTF-8&useSSL=false
- jdbc.user = root
- jdbc.password =123456
复制代码- # Maven的POM文件处理
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.47</version>
- </dependency>
复制代码 3.4.2 MySQL 8.0
推荐使用MySQL8.0- # mysql8.0---JDBC四件套
- jdbc.driverClass = com.mysql.cj.jdbc.Driver
- jdbc.url= jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
- jdbc.user = root
- jdbc.password =123456
复制代码- # Maven的POM
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.11</version>
- </dependency>
复制代码 4.Mapper4之一键生成
4.1 mybatis-generator
http://mybatis.org/generator
一款生成mapper的插件。
4.2 MyBatis通用Mapper4官网
https://github.com/abel533/Mapper
4.3 Mapper5官网
https://github.com/mybatis-generator/mapper
4.4 一键生成步骤
4.4.1 建表SQL
- #注意,只提供了建表sql,要自己建立数据库。演示sql,无实际意义。
- DROP TABLE IF EXISTS `t_pay`;
- CREATE TABLE `t_pay` (
- `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
- `pay_no` VARCHAR(50) NOT NULL COMMENT '支付流水号',
- `order_no` VARCHAR(50) NOT NULL COMMENT '订单流水号',
- `user_id` INT(10) DEFAULT '1' COMMENT '用户账号ID',
- `amount` DECIMAL(8,2) NOT NULL DEFAULT '9.9' COMMENT '交易金额',
- `deleted` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0' COMMENT '删除标志,默认0不删除,1删除',
- `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- PRIMARY KEY (`id`)
- ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='支付交易表';
- INSERT INTO t_pay(pay_no,order_no) VALUES('pay17203699','6544bafb424a');
- SELECT * FROM t_pay;
复制代码 4.4.2 创建generator模块
略
4.4.3 POM
4.4.4 设置
resource文件夹下
config.properties- #User表包名
- package.name=com.atguigu.cloud
- # mysql5.7
- jdbc.driverClass = com.mysql.jdbc.Driver
- jdbc.url= jdbc:mysql://localhost:3306/db2024?useUnicode=true&characterEncoding=UTF-8&useSSL=false
- jdbc.user = root
- jdbc.password =123456
- #或
- #t_pay表包名
- package.name=com.atguigu.cloud
- # mysql8.0
- jdbc.driverClass = com.mysql.cj.jdbc.Driver
- jdbc.url= jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
- jdbc.user = root
- jdbc.password =123456
复制代码 generatorConfig.xml- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE generatorConfiguration
- PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
- "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
- <generatorConfiguration>
- <properties resource="config.properties"/>
- <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
- <property name="beginningDelimiter" value="`"/>
- <property name="endingDelimiter" value="`"/>
- <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
- <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
- <property name="caseSensitive" value="true"/>
- </plugin>
- <jdbcConnection driver
- connectionURL="${jdbc.url}"
- userId="${jdbc.user}"
- password="${jdbc.password}">
- </jdbcConnection>
- <javaModelGenerator targetPackage="${package.name}.entities" targetProject="src/main/java"/>
- <sqlMapGenerator targetPackage="${package.name}.mapper" targetProject="src/main/java"/>
- <javaClientGenerator targetPackage="${package.name}.mapper" targetProject="src/main/java" type="XMLMAPPER"/>
- <table tableName="t_pay" domainObjectName="Pay">
- <generatedKey column="id" sqlStatement="JDBC"/>
- </table>
- </context>
- </generatorConfiguration>
复制代码 4.4.5 点击插件运行既可
5.通用Base工程构建
5.1 v1工程
cloud-provider-payment8001为例
5.1.1 微服务小口诀
- 1.建module
- 2.改POM
- 3.写YML
- 4.主启动
- 5.业务类
5.1.2 步骤
建module
略,创建完成后,父工程pom文件会多一个- <modules>
- <module>generator</module>
- <module>cloud-provider-payment8001</module>
- </modules>
复制代码 改POM- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>com.atguigu.cloud</groupId>
- <artifactId>mscloudV5</artifactId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <artifactId>cloud-provider-payment8001</artifactId>
- <properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
- <dependencies>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-actuator</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid-spring-boot-starter</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springdoc</groupId>
- <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- </dependency>
-
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- </dependency>
-
- <dependency>
- <groupId>javax.persistence</groupId>
- <artifactId>persistence-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>tk.mybatis</groupId>
- <artifactId>mapper</artifactId>
- </dependency>
-
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-all</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba.fastjson2</groupId>
- <artifactId>fastjson2</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.28</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- </project>
复制代码 写yml- server:
- port: 8001
- # ==========applicationName + druid-mysql8 driver===================
- spring:
- application:
- name: cloud-payment-service
- datasource:
- type: com.alibaba.druid.pool.DruidDataSource
- driver-class-name: com.mysql.cj.jdbc.Driver
- #连接的url替换为自己安装的端口好,和数据库
- url: jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
- username: xxx 替换为自己账号
- password: xxx 替换为自己密码
- # ========================mybatis===================
- mybatis:
- mapper-locations: classpath:mapper/*.xml
- type-aliases-package: com.atguigu.cloud.entities
- configuration:
- map-underscore-to-camel-case: true
复制代码 主启动- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import tk.mybatis.spring.annotation.MapperScan;
- /**
- * @auther zzyy
- * @create 2023-11-03 17:54
- */
- @SpringBootApplication
- @MapperScan("com.atguigu.cloud.mapper") //import tk.mybatis.spring.annotation.MapperScan;
- public class Main8001
- {
- public static void main(String[] args)
- {
- SpringApplication.run(Main8001.class,args);
- }
- }
复制代码 业务类
略
5.1.3 测试
Swagger3常用注解
注解标注位置作用@TagContoller类标识Controller@Paramter参数标识参数@Paramters参数参数多重说明@SchemaModel层的JavaBean或DTO形貌模型作用及每个属性@Operation方法形貌方法作用@ApiResponse方法形貌响应状态码举例- @Tag(name = "支付微服务模块", description = "支付CRUD")
- public class PayController {
-
- @Operation(summary = "新增", description = "新增支付流水方法,json串做参数")
- public ResultData<String> addPay(@RequestBody Pay pay) {
-
- @Schema(title = "支付交易表Entity")
- public class Pay {
-
- /**
- * 订单流水号
- */
- @Schema(title = "订单流水号")
- private String orderNo;
复制代码 设置类- import io.swagger.v3.oas.models.ExternalDocumentation;
- import io.swagger.v3.oas.models.OpenAPI;
- import io.swagger.v3.oas.models.info.Info;
- import org.springdoc.core.models.GroupedOpenApi;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- /**
- * @auther zzyy
- * @create 2023-11-04 10:40
- */
- @Configuration
- public class Swagger3Config
- {
- @Bean
- public GroupedOpenApi PayApi()
- {
- return GroupedOpenApi.builder().group("支付微服务模块").pathsToMatch("/pay/**").build();
- }
- @Bean
- public GroupedOpenApi OtherApi()
- {
- return GroupedOpenApi.builder().group("其它微服务模块").pathsToMatch("/other/**", "/others").build();
- }
- /*@Bean
- public GroupedOpenApi CustomerApi()
- {
- return GroupedOpenApi.builder().group("客户微服务模块").pathsToMatch("/customer/**", "/customers").build();
- }*/
- @Bean
- public OpenAPI docsOpenApi()
- {
- return new OpenAPI()
- .info(new Info().title("cloud2024")
- .description("通用设计rest")
- .version("v1.0"))
- .externalDocs(new ExternalDocumentation()
- .description("www.atguigu.com")
- .url("https://yiyan.baidu.com/"));
- }
- }
复制代码 5.1.4 上述模块存在的问题
1.时间格式
返回的时间格式不是yyyy-MM-dd HH:mm:ss
2.统一计划API接口实现统一格式返回
3 全局非常接入返回的尺度格式
5.2 v2工程
5.2.1 解决时间格式问题
1.使用@JsonFormat注解- /**
- * 创建时间
- */
- @Column(name = "create_time")
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GBT+8")
- private Date createTime;
- /**
- * 更新时间
- */
- @Column(name = "update_time")
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GBT+8")
- private Date updateTime;
复制代码 2.Spring Boot项目,也可以在application.yml文件中指定:- #建议使用该方式
- spring:
- jackson:
- date-format: yyyy-MM-dd HH:mm:ss
- time-zone: GMT+8
复制代码 5.2.2 解决统一返回值
思绪:定义返回尺度格式,三大标配:
- code状态值:由后端统一定义各种返回结果的状态码。
- message形貌:本次接口调用结果的形貌。
- data数据:本次返回的数据。
扩展:接口调用时间:
新建枚举类- import java.util.Arrays;
- public enum ReturnCodeEnum {
- /**
- * 操作失败
- **/
- RC999("999", "操作XXX失败"),
- /**
- * 操作成功
- **/
- RC200("200", "success"),
- /**
- * 服务降级
- **/
- RC201("201", "服务开启降级保护,请稍后再试!"),
- /**
- * 热点参数限流
- **/
- RC202("202", "热点参数限流,请稍后再试!"),
- /**
- * 系统规则不满足
- **/
- RC203("203", "系统规则不满足要求,请稍后再试!"),
- /**
- * 授权规则不通过
- **/
- RC204("204", "授权规则不通过,请稍后再试!"),
- /**
- * access_denied
- **/
- RC403("403", "无访问权限,请联系管理员授予权限"),
- /**
- * access_denied
- **/
- RC401("401", "匿名用户访问无权限资源时的异常"),
- RC404("404", "404页面找不到的异常"),
- /**
- * 服务异常
- **/
- RC500("500", "系统异常,请稍后重试"),
- RC375("375", "数学运算异常,请稍后重试"),
- INVALID_TOKEN("2001", "访问令牌不合法"),
- ACCESS_DENIED("2003", "没有权限访问该资源"),
- CLIENT_AUTHENTICATION_FAILED("1001", "客户端认证失败"),
- USERNAME_OR_PASSWORD_ERROR("1002", "用户名或密码错误"),
- BUSINESS_ERROR("1004", "业务逻辑异常"),
- UNSUPPORTED_GRANT_TYPE("1003", "不支持的认证模式");
- private final String code;
- private final String message;
- ReturnCodeEnum(String code, String message) {
- this.code = code;
- this.message = message;
- }
- public String getCode() {
- return code;
- }
- public String getMessage() {
- return message;
- }
- public static ReturnCodeEnum getReturnCodeEnum(String code) {
- for (ReturnCodeEnum rce : ReturnCodeEnum.values()) {
- if (rce.getCode().equals(code)) {
- return rce;
- }
- }
- return null;
- }
- public static ReturnCodeEnum getReturnCodeEnumV2(String code) {
- return Arrays.stream(ReturnCodeEnum.values())
- .filter(r -> r.getCode().equals(code))
- .findFirst()
- .orElse(null);
- }
- }
复制代码 新建统一定义返回对象ResultData- import lombok.Data;
- import lombok.experimental.Accessors;
- @Data
- @Accessors(chain = true)
- public class ResultData<T> {
- private String code;
- private String message;
- private T data;
- private long timestamp;
- public ResultData(){
- this.timestamp = System.currentTimeMillis();
- }
- public static <T> ResultData<T> success(T data){
- ResultData<T> resultData = new ResultData<>();
- resultData.setCode(ReturnCodeEnum.RC200.getCode());
- resultData.setMessage(ReturnCodeEnum.RC200.getMessage());
- resultData.setData(data);
- return resultData;
- }
- public static <T> ResultData<T> fail(String code,String message){
- ResultData<T> resultData = new ResultData<>();
- resultData.setCode(code);
- resultData.setMessage(message);
- return resultData;
- }
- }
复制代码 修改PayController
略
测试
略
5.2.3 全局非常接入返回的尺度格式
新建全局非常类- import com.atguigu.cloud.resp.ResultData;
- import com.atguigu.cloud.resp.ReturnCodeEnum;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.http.HttpStatus;
- import org.springframework.web.bind.annotation.ExceptionHandler;
- import org.springframework.web.bind.annotation.ResponseStatus;
- import org.springframework.web.bind.annotation.RestControllerAdvice;
- @Slf4j
- @RestControllerAdvice
- public class GlobalExceptionHandler {
- /**
- * 默认全局异常处理
- * @param e
- * @return
- */
- @ExceptionHandler(RuntimeException.class)
- @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
- public ResultData<String> exception(Exception e) {
- logger.error("----come in GlobalExceptionHandler");
- log.error("全局异常信息exception:{}", e.getMessage(), e);
- return ResultData.fail(ReturnCodeEnum.RC500.getCode(),e.getMessage());
- }
- }
复制代码 修改Controller
略
6.引入微服务概念
6.1 订单微服务,如何才能调用到支付微服务8001
6.2 新建cloud-consumer-order80
不外,80端口,是HTTP协议的默认端口,一般开启浏览器,都会占用,所以修改为其他的端口即可,这里模块名未做修改。
这里,建moudle,改pom,写yml,主启动,业务类,都略,只是记笔记,不能再将编码,都重复一变,见视频
记一下,其中的核心的东西
新创建了PayDTO,用以微服务间的数据传输的载体。- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import java.io.Serializable;
- import java.math.BigDecimal;
- /**
- * @author 长名06
- * @year 2024
- * 一般而言,调用者不应该获悉服务提供者的entity资源并知道表结构关系,所以服务提供方给出的
- * 接口文档都都应成为DTO
- */
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class PayDTO implements Serializable {
- private Integer id;
- /**
- * 支付流水号
- */
- private String payNo;
- /**
- * 订单流水号
- */
- private String orderNo;
- /**
- * 用户账号ID
- */
- private Integer userId;
- /**
- * 交易金额
- */
- private BigDecimal amount;
- }
复制代码 6.3 RestTemplate
RestTemplate提供了多种便捷访问远程Http服务的方法, 是一种简朴便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集。
restful可以看作是一种构建头脑,也可以看作,标志服务器资源的协议(约定可能更合适)。好比Post接口,一般都是新增,Get接口,是查询等,都是Restful的表现。
官网地址
使用restTemplate访问restful接口非常的简朴粗暴无脑。
(url, requestMap, ResponseBean.class)这三个参数分别代表
REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
具体见官网API说明,这些东西,记不住,也正常。毕竟在盘算机的世界里,要学的东西着实是太多了,学东西重要的是明白其头脑。记不住就找笔记,或百度,问生成式AI都可以。
6.4 RestTemplate设置类
- import org.springframework.cloud.client.loadbalancer.LoadBalanced;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.client.RestTemplate;
- @Configuration
- public class RestTemplateConfig {
- @Bean
- @LoadBalanced
- public RestTemplate restTemplate(){
- return new RestTemplate();
- }
- }
复制代码 6.5 OrderController
- import com.atguigu.cloud.dto.PayDTO;
- import com.atguigu.cloud.resp.ResultData;
- import jakarta.annotation.Resource;
- import org.springframework.web.bind.annotation.*;
- import org.springframework.web.client.RestTemplate;
- @RestController
- @RequestMapping("/consumer")
- public class OrderController {
- public static final String PAYMENT_SRV_URL = "http://localhost:8001";//硬编码
- @Resource
- private RestTemplate restTemplate;
- /**
- * 一般情况下,通过浏览器的地址栏输入url,发送的只能是get请求
- * 我们底层调用的是post方法,模拟消费者发送get请求,客户端消费者
- * 参数可以不添加@RequestBody
- * @param payDTO
- * @return
- */
- @GetMapping("/pay/add")
- public ResultData addOrder(PayDTO payDTO){
- return restTemplate.postForObject(PAYMENT_SRV_URL + "/pay/add",payDTO,ResultData.class);
- }
- @GetMapping("/pay/get/{id}")
- public ResultData getPayInfo(@PathVariable("id") Integer id){
- return restTemplate.getForObject(PAYMENT_SRV_URL + "/pay/get/" + id,ResultData.class,id);
- }
- @DeleteMapping("/pay/delete/{id}")
- public void deletePay(@PathVariable("id") Integer id){
- restTemplate.delete(PAYMENT_SRV_URL + "/pay/delete/"+id);
- }
- @GetMapping("/pay/update")
- public void updatePay(PayDTO payDTO){
- restTemplate.put(PAYMENT_SRV_URL + "/pay/update",payDTO);
- }
- }
复制代码 测试略
6.6 工程重构
将PayDTO,ResultData,ReturnCodeEnum类提到common模块,打包到本地库,以及修改Order80,Pay8001的类和POM的修改,这些都略。
6.7 硬编码问题
微服务所在的IP地址和端口号硬编码到订单微服务中,会存在非常多的问题
- (1)如果订单微服务和支付微服务的IP地址或者端口号发生了变革,则支付微服务将变得不可用,需要同步修改订单微服务中调用支付微服务的IP地址和端口号。
- (2)如果系统中提供了多个订单微服务和支付微服务,则无法实现微服务的负载平衡功能。
- (3)如果系统需要支持更高的并发,需要摆设更多的订单微服务和支付微服务,硬编码订单微服务则后续的维护会变得非常复杂。
所以,在微服务开辟的过程中,需要引入服务治理功能,实现微服务之间的动态注册与发现,从此刻开始我们正式进入SpringCloud实战。
只是为了记录自己的学习历程,且本人程度有限,不对之处,请指正。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |