# penguin-spring-boot
**Repository Path**: BeiZhanYuChun/penguin-spring-boot
## Basic Information
- **Project Name**: penguin-spring-boot
- **Description**: SpringBoot的集成实现
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2020-12-30
- **Last Updated**: 2023-05-31
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# penguin-spring-boot
#### 介绍
SpringBoot的集成实现
#### 软件架构
SpringBoot+SpringCloud+SpringAlibabaCloud作为服务框架支持
- elasticsearch: 作为服务搜索引擎
- sentinel: 阿里巴巴的sentinel作为服务的服务熔断器
- nacos:阿里巴巴的nacos作为服务的注册中心
- nacos:阿里巴巴的nacos作为服务的配置中心
#### 安装教程
1. mvn clean package -DskipTests
2. 复制[spring-cloud-runner]中target的jar包
3. java -jar spring-cloud-runner.jar启动
#### 项目说明
- penguin-spring-cloud
- spring-cloud-core
- com.pkk.spring.cloud.core.autoconfigure: 自动装配新定义的配置和BEAN
- com.pkk.spring.cloud.core.support : 自动装配一些初始化配置的配置;eg:响应序列化
#### 使用说明
1. Java基础开发原则

2. Spring的主要模块

3. Spring项目的选型

```markdown
服务注册中心:
Eureka:官方停止更新,并且已经有更好的替代产品了,可以使用,但是官方已经不建议使用了(重度患者)。
Zookeeper:某些老系统,以前是用的Zookeeper + Dubbo,后来做技术升级,结果发现SpringCloud的Eureka停更了,然后就用了最少的技术切换,那么就用了Zookeeper做注册中心。
Consul:go语言开发的,也是一个优秀的服务注册框架,但是使用量较少,风头都被Nacos抢了。
Nacos:来自于SpringCloudAlibaba,在企业中经过了百万级注册考验的,不但可以完美替换Eureka,还能做其他组件的替换,所以强烈建议使用,是学习的重点。
服务调用:
Ribbon:也进入了维护状态,停止更新了,但是Spring官方还在使用(轻度患者)。
LoadBalancer:Spring官方推出的一个新的组件,打算逐渐取代掉Ribbon,但是现在还处于萌芽状态。
服务调用2:
Feign:Netflix 公司产品,也停止更新了。
OpenFeign:Spring社区等不了Netflix更新了,然后就自己做了一个组件,不用Feign了。
服务降级:
Hystrix:官网不推荐使用,但是中国企业中还在大规模使用。
Resilience4J:官网推荐使用,但是国内很少用这个。
Sentienl:来自于SpringCloudAlibaba,在中国企业替换Hystrix的组件,国内强烈建议使用。
服务网关:
Zuul:Netflix 公司产品,公司内部产生分歧,有的人想自己出一个Zuul2。
Zuul2:也是Netflix 公司准备出的产品,但是由于内部分歧,所以Zuul2已经胎死腹中了。
gateway:Spring社区自己出的网关组件,官方隆重介绍和极度推荐的网关服务组件。
服务配置:
Config:目前也在使用,风头被Nacos抢了。
Nacos:来自于SpringCloudAlibaba,后来居上,把Config给替换了。
服务总线:
Bus:SpringCloud原生的服务总线组件,现在风头也被Nacos抢了。
Nacos:来自于SpringCloudAlibaba,后来居上,把Bus给替换了。
```
- 服务调用负载均衡的选型
> Ribbon已经停更进维了
- 服务注册中心的选型

- 服务降级的选型

4. 分布式不可避免的CAP选择
- 基础认知
- C: (Consistency) 分区强一致性,多个集群之间保持数据的最终一致性
- A: (Availability) 分区的高可用性,集群保证一致性的过程中,对外可能无法保证服务可用性(同步中)
- P: (Partition tolerance) 分区的容错性,分布式中必不可少的,分布式系统中如果部分网络中断,
则部分服务无法对外提供,数据则被分散在不同的网络片段中,这称之为分区,当数据只在这一个节点中存在,
又因为无法与外界联通,这就导致了分区无法容忍了。
- 大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。分区容错的意思是,区间通信可能失败。比如,一台服务器放在中国,另一台服务器放在美国,这就是两个区,它们之间可能无法通信
- 分区容错性的理解

#### 扩展知识
- JavaClass基础方法的介绍

#### 问题解决集
1. 消息转换器MessageConverter的设置

```markdown
> 依赖说明
com.fasterxml.jackson.core
jackson-databind
com.fasterxml.jackson.datatype
jackson-datatype-jsr310
> 说明
- @RestControllerAdvice会触发ResponseBodyAdvice的处理
- ResponseBodyAdvice是带消息转换器处理之后调用其write方法之前调用,可以对数据的统一返回控制
> 问题
- 统一返回之后,原先返回的String现在转为统一返回的另外一个类型Object则会出现转化异常
- 异常示例:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: class com.pkk.spring.cloud.core.common.rpc.response.ResponseBody cannot be cast to class java.lang.String (com.pkk.spring.cloud.core.common.rpc.response.ResponseBody is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-5.3.1.jar:5.3.1]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.1.jar:5.3.1]
- 问题说明
Spring默认的String消息处理器会优先级较高于此处理器(优先处理并返回),假如我们返回的是String字符串这里我们又封装了为@ResponseBody类型的,会导致转换异常
- 解决问题
1. 我们判断如果是String,则将其转换为ResponseBody类型然后再转为String字符串
if(o instanceof String){
return new ObjectMapper().writeValueAsString(R.success(o));
}
2. 我们也可以将此jackson消息处理器优先于Spring的String处理器处理
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List> converters) {
// 第一种方式是将 json 处理的转换器放到第一位,使得先让 json 转换器处理返回值,这样 String转换器就处理不了了。
// converters.add(0, new MappingJackson2HttpMessageConverter());
// 第二种就是把String类型的转换器去掉,不使用String类型的转换器
// converters.removeIf(httpMessageConverter -> httpMessageConverter.getClass() == StringHttpMessageConverter.class);
}
}
```
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)