本人不是专业的后端开发,以下只代表个人看法,如有问题请指出。博客时间:2021-12-15
背景
一般的计算场景为例,实时计算需要计算用户从有第一笔订单到目前的所有订单总和,这里的时间维度为最开始到当前时刻。所以将汇总计算下推到TiDB中,flink接收到消息后执行sql获取汇总返回值。开发实时任务需要写大量的SQL同时为了方便执行需要引入mybatis。但是单独引入mybatis会导致数据库连接一直开关。所以是准备引入Springboot来整合mybatis。
目标
希望将flink的开发变成和Springboot注解开发一样,提高开发效率。
具体实践
通过nacos拉取配置消息,然后初始化连接池。然后在flink function中使用的对应的mapper文件,使用@Autowired注入然后调用对应的方法,但是在调用function类用的都是new此时会抛出NullPointerException。解决方案一 不使用@Autowired 而且在open中通过getBean()获取对应的实例,但是这样违背了注解开发的意愿。解决方案二 在调用function类的实例上加上@Component,那么flink的启动类上也需要加上注解否则也是会出现null的情况。
反思:Springboot整合flink是否是一条正确的道路,在spring的容器中启动flink任务是否是正确的?而且需要启动flink的集群。
第二个思路
将后台的查询数据库,调用接口等操作封装到一个专用服务(Springboot)中,flink通过grpc调用Springboot中对应的方法。
此方案需要将flink尽量做到抽象,最好只有source+fn,sink可以放在grpc中处理或者在flink中处理,其他的etl逻辑都放在grpc中处理,来保证处理逻辑的连贯性。
为了减少flink代码的改动,可以做一个通用的entryGrpc,不管是什么任务都可以调用这个entryGrpc来减少flink层的变动(这样开发人员只需要关注实时任务的逻辑,而不需要关注proto文件怎么写,因为proto文件中只会存在一个方法那就是entry())。然后在Springboot项目的entry()中做路由,路由到真正的处理逻辑中。
问题:因为所有的grpc都调用的同一个接口会导致grpc连接数量达到上线
可以设置grpc连接数量的上线
尝试引入了spring-cloud-gateway-grpc 里面的路由规则是按照path来分发请求,path就是proto文件中的包名+方法名。但是我需要根据proto文件中requestMessage中的字段值来做分发,那么在网关层就需要解析grpc的消息,同时在通过newBlockingStub()方法进行调用。newBlockingStub()方法的调用是需要指定proto文件中的方法名称的,但是proto文件中只有entry()一个方法。
考虑在flink调用网关时能否在header中塞入一些字段,然后网关层做一定的解析调用到真正的方法中,如何绕过newBlockingStub()方法的调用是个问题。
是否可以考虑放弃grpc走http,设置http中的header值然后通过spring-cloud-gateway解析路由到真正的处理逻辑接口中。