前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >austin升级为SpringCloud架构!

austin升级为SpringCloud架构!

作者头像
Java3y
发布2024-06-14 20:14:07
810
发布2024-06-14 20:14:07
举报
文章被收录于专栏:Java3yJava3y

之前有很多同学都问过,austin是不是一个分布式系统。我当时是这样回答的:

可以明确地告诉大家,austin并不是「分布式」「微服务」的项目。目前到此为止,它核心就只有一个发送的接口,而且只能通过HTTP的方式去调用。

那他能做成一个「分布式」项目吗?答案也是可以的,只要把「服务治理」相关的组件引入就可以问题了。

现在是项目是分开module模块的,austin-web(管理后台)/austin-cron(定时任务)/austin-apiaustin-api-impl(接入层)/austin-handler(下发逻辑处理层)这几个都可以单独抽出来部署。

(实际上在生产环境里,也是这么干的)

单独部署了以后,再通过「服务治理」的组件进行管理,那系统就是「分布式」的架构了。听着听不难,对不对?实际上也确实不难。

既然如此,为什么我一直都没去变动我的系统呢?最核心的点在于:我认为以我这类系统来说,功能的完整性比「分布式」这种架构模式更加重要。

最近有空了,我打算把austin整成是分布式的系统,说干就干

现在市面上用Spring Cloud Alibaba 是比较多了,所以我打算在austin上也使用它作为服务治理的鸡架。

SpringCloud版本选择

JDK和SpringBoot的版本决定着Spring Cloud Alibaba使用什么版本:

  • 2023.x 分支对应的是 Spring Cloud 2023 与 Spring Boot 3.2.x,最低支持 JDK 17。
  • 2022.x 分支对应的是 Spring Cloud 2022 与 Spring Boot 3.0.x,最低支持 JDK 17。
  • 2021.x 分支对应的是 Spring Cloud 2021 与 Spring Boot 2.6.x,最低支持 JDK 1.8

由于austin在构建的时候,使用的是JDK 1.8SpringBoot 2.5.6。本着以最低的成本升级,我决定使用2021.x版本,并把SpringBoot升级到2.6.13版本

升级SpringBoot版本遇到的问题1

如果现在有个A对象,它的属性是B对象,而B对象的属性也是A对象。说白了就是A依赖B,而B又依赖A,这就叫做循环依赖。

Spring 2.6.x 之后,无论什么形式的循环依赖默认都是禁止的,需要手动在配置文件开启:spring.main.allow-circular-references=true

升级SpringBoot版本遇到的问题2

swagger是文档工具,在SpringBoot使用时,一般我们会添加以下依赖:

代码语言:javascript
复制

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

但升级到SpringBoot 2.6.x时启动就会报错,很明显就是版本不兼容呗。

代码语言:javascript
复制

org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
    .......

解决方案:

  1. 添加配置文件:
代码语言:javascript
复制

spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER

  1. 添加代码配置:
代码语言:javascript
复制

    @Bean
    public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
        return new BeanPostProcessor() {

            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
                if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
                    customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
                }
                return bean;
            }

            private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
                List<T> copy = mappings.stream()
                        .filter(mapping -> mapping.getPatternParser() == null)
                        .collect(Collectors.toList());
                mappings.clear();
                mappings.addAll(copy);
            }

            @SuppressWarnings("unchecked")
            private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
                try {
                    Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
                    field.setAccessible(true);
                    return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    throw new IllegalStateException(e);
                }
            }
        };
    }

分布式架构后,路径配置扫描问题

austin之前只有一个入口类,在模块austin-web包下,路径为:com.java3y.austin.AustinApplication

不少人很好奇,为什么austin-support下config中@Value注解如何拿到austin-web下yml中的值?没有看到开启MapperScanner也能生成代理类?

原因很简单,启动类是在com.java3y.austin这个路径下的,其他的模板都是基于com.java3y.austin.*之上的。

SpringBoot在启动时,如果没有指定,默认会把当前启动类的路径当做扫描路径,所以其他的模块的对象&配置都能注入。

当升级为分布式时,则需要指定对应的路径扫描对应的包

将服务注册到注册中心

austin-service-api-impl模块为例,在原来的基础上,注册服务大致有以下步骤:

1、 增加 spring-cloud-starter-alibaba-nacos-discoveryspring-boot-starter-web 的maven依赖

2、 增加 spring-boot-maven-plugin 打包plugin

3、 增加 单独的 Application 启动类

4、 暴露接口,注册服务

服务启动后,就可以在nacos上看到应用被注册到注册中心上了。

消费服务

austin-web模块为例,在原来的基础上,消费服务大致有以下步骤:

1、 增加 spring-cloud-starter-alibaba-nacos-discoveryspring-cloud-starter-openfeignspring-cloud-starter-loadbalancer的maven依赖

2、 增加 FeignClient的配置信息

3、 使用 FeignClient代理类去调用服务

代码语言:javascript
复制

/**
 * @author 3y
 * austin-service-impl模块的接口
 */
@FeignClient(name = "austin-service")
public interface AustinServiceRpc {
    @RequestMapping(value = "/send")
    SendResponse send(@RequestBody SendRequest sendRequest);

    @RequestMapping(value = "/batchSend")
    SendResponse batchSend(@RequestBody BatchSendRequest batchSendRequest);

    @RequestMapping(value = "/recall")
    SendResponse recall(@RequestBody SendRequest sendRequest);

    @RequestMapping(value = "/traceByMessageId")
    TraceResponse traceByMessageId(@RequestBody String messageId);
}

后续

项目还在改造中,主要就是每一个都要单独拆开来。后续有应该会把austin-support模块再拆细点,也会把本地的队列的代码给删掉(都分布式远程交互了,本地的队列代码就没有意义了)

暂时打算开源的仓库不动,可能重新开个新的仓库,就叫austin-cloud好了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java3y 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SpringCloud版本选择
  • 升级SpringBoot版本遇到的问题1
  • 升级SpringBoot版本遇到的问题2
  • 分布式架构后,路径配置扫描问题
  • 将服务注册到注册中心
  • 消费服务
  • 后续
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档