V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hahahenimei
V2EX  ›  Java

关于 SpringBoot 并发处理的问题

  •  
  •   hahahenimei · 2023-09-13 08:14:10 +08:00 · 4338 次点击
    这是一个创建于 429 天前的主题,其中的信息可能已经有所发展或是发生改变。

    公司有个小程序,本应该是直接调用 B 服务的,但是现在是小程序调用 A 服务的接口,A 的接口中调用 B 服务中的接口获取返回值( A 服务主要是构造调用 B 服务用到的 token )。现在想重构这个 A 服务,想要提高并发处理的能力。有没有好的建议。

    30 条回复    2023-09-17 12:17:16 +08:00
    chaos93
        1
    chaos93  
       2023-09-13 08:21:31 +08:00   ❤️ 2
    针对提高并发处理能力,以下是一些建议:

    1. 引入缓存:可以使用缓存来存储 B 服务的 token ,避免每次请求都需要调用 B 服务接口获取 token 。可以选择使用内存缓存或者分布式缓存,根据实际情况选择合适的缓存方案。

    2. 异步处理:将 A 服务的接口调用 B 服务的逻辑改为异步处理,可以使用消息队列或者异步任务来实现。当小程序调用 A 服务的接口时,A 服务将请求放入消息队列或者异步任务中,然后立即返回响应给小程序,不需要等待 B 服务的返回结果。这样可以提高并发处理能力。

    3. 并发请求:可以使用并发请求的方式来调用 B 服务的接口,以提高处理能力。可以使用多线程、线程池或者异步框架来实现并发请求。

    4. 服务拆分:如果 A 服务的并发处理能力仍然不足,可以考虑将 A 服务拆分成多个微服务,每个微服务负责不同的功能模块。这样可以将负载分散到多个服务上,提高整体的并发处理能力。

    5. 优化代码:对 A 服务的代码进行优化,提高代码的执行效率。可以通过优化算法、减少不必要的计算、减少数据库查询等方式来提高代码的性能。

    综上所述,以上是一些提高 A 服务并发处理能力的建议。根据具体情况选择合适的方案进行重构。
    matepi
        2
    matepi  
       2023-09-13 08:24:36 +08:00   ❤️ 1
    LZ 得讲清楚限制并发的限制在哪里?
    A 、B 现在有各多少能力,限制资源在 B 还是在 A 内的其他部分。交易场景可异步化程度如何。

    如果只是构造 token ,假设你 token 需要 GUID 类似的全局唯一控制,那么 A 本身的生成 token 动作基本不应该受什么并发限制。如果 A 构造了 token 之后,A 还向 redis 等设施缓存,那么问题就变成 A->redis 的并发能力有多少。如果 redis 并发能力不够,是否要 redis 自身集群化;或按其他交易标识等信息 hash 化之后,分交易集群分别独立处理链条的方式。

    如果 B 有并发能力限制,那么还要问 A->B 的请求是必须同步等待返回的,还是可以异步的;又还要问,A 是否可以对用户异步,是否可队列化请求,异步返回等等。

    LZ 需求题干给的信息偏少,建议思路会很发散的。
    hahahenimei
        3
    hahahenimei  
    OP
       2023-09-13 08:41:06 +08:00
    @matepi 多谢老哥的回答。因为 B 的服务是买的供应商提供的接口。所以现在只考虑 A 服务的并发处理能力,提高 A 的并发限制。现在用 Nginx 负载+服务 A 集群 的方式来实现。的确 A 会向 redis 进行缓存。老哥说的 A-> Redis 这块没考虑过,可以往集群上考虑。领导开会是准备重构这个项目 看看有没有更好的实现,因为对于 A 服务来说,只是构造了 token 转发了请求,所以在考虑能不能用其他的实现方式来解决。
    tairan2006
        4
    tairan2006  
       2023-09-13 08:43:53 +08:00
    把 A 的逻辑换成 OpenResty 或者 ApiSix 中的 lua 脚本
    Goooooos
        5
    Goooooos  
       2023-09-13 08:48:15 +08:00
    是否考虑 A 只生成并返回 token ,获得 token 后别的服务直接调用 B
    hahahenimei
        6
    hahahenimei  
    OP
       2023-09-13 08:53:30 +08:00
    @tairan2006 @Goooooos 感谢二位老哥,我去看一下。多谢!
    allenzhangSB
        7
    allenzhangSB  
       2023-09-13 09:29:19 +08:00
    把 A 服务换成网关(spring cloud gateway, shenyu), 然后在网关内处理 token 就可以了
    byte10
        8
    byte10  
       2023-09-13 09:45:20 +08:00
    不要考虑高并发啦,一个小程序没啥高并发的吧。token 可以上缓存,redis 不用考虑高并发,它都能是瓶颈的话(除非代码问题)那么你们公司估计都能上市了。springboot 的 servlet 支持异步请求,你可以用支持异步的 httpclient 客户端,连接数设置 1000 个,单独这个 token 业务接口 单机 2 核 1G 上 1W+/s 不是问题。
    iblessyou
        9
    iblessyou  
       2023-09-13 09:46:28 +08:00   ❤️ 1
    哈哈哈,一楼写的那么有条理,一眼 AI 。 原来 AI 会因为太聪明而不是太笨被识破
    chaos93
        10
    chaos93  
       2023-09-13 09:51:46 +08:00
    @hahahenimei 为什么不谢我
    keeley
        11
    keeley  
       2023-09-13 10:16:48 +08:00
    @chaos93 你应该是 ai 回复的。
    a1274598858
        12
    a1274598858  
       2023-09-13 10:24:51 +08:00
    @chaos93 #10 这答案 GPT 给的吧。。🙀
    j1132888093
        13
    j1132888093  
       2023-09-13 10:25:37 +08:00
    @chaos93 #1 在 V 站用 GPT 回复是会被封号的 https://www.v2ex.com/help/assertive
    hahahenimei
        14
    hahahenimei  
    OP
       2023-09-13 11:04:11 +08:00
    @allenzhangSB 多谢老哥,我去试下。 @byte10 好的,虽然。。但是。。 领导给的任务是这个。自己也想重构的好一点,找个完备的方案,以后用来吹牛逼。
    hahahenimei
        15
    hahahenimei  
    OP
       2023-09-13 11:05:16 +08:00
    @chaos93 感谢老哥,回答的很详细。
    allenzhangSB
        16
    allenzhangSB  
       2023-09-13 11:15:21 +08:00 via iPhone
    @hahahenimei 其实既然使用 spring 的话,用 spring webflux 加 webclient 就可以了
    chaos93
        17
    chaos93  
       2023-09-13 11:17:01 +08:00   ❤️ 1
    @j1132888093 我是让 AI 帮我优化有没有错别字
    VB1
        18
    VB1  
       2023-09-13 13:33:42 +08:00
    2L 说的没毛病,给的信息太少了,提高并发无非两点,1.降低单个接口响应时间(提高下限)。2.扩容机器数量接收更多请求(提高上限)。现在看你描述的场景,根本不知道是哪里的问题。
    quan7u
        19
    quan7u  
       2023-09-13 14:05:40 +08:00
    @a1274598858
    @j1132888093 你们是两兄弟吗?
    zzsong
        20
    zzsong  
       2023-09-13 14:18:40 +08:00 via iPhone
    如果仅仅只是加了个 tokrn 的话,那在 gateway 里写个 filter 会是一个既简单又高效的方案。
    a1274598858
        21
    a1274598858  
       2023-09-13 14:34:33 +08:00   ❤️ 1
    @quan7u #19 我们都是真爱粉
    miaotaizi
        22
    miaotaizi  
       2023-09-13 14:40:34 +08:00
    这个问题跟 SpringBoot 啥关系?
    Huelse
        23
    Huelse  
       2023-09-13 15:11:04 +08:00
    一般 SpringBoot 优化都是很好的,最终压力都给在机器硬件性能、数据库性能和网络性能上。
    lyxeno
        24
    lyxeno  
       2023-09-13 17:13:38 +08:00
    先跑个 Profile,做个压测看看瓶颈在哪里?
    hakr
        25
    hakr  
       2023-09-13 18:13:23 +08:00
    @chaos93 #1 如果让 gpt 警察看到了并且艾特了站长你这个号就要废了-.-
    zhaokun
        26
    zhaokun  
       2023-09-13 21:24:14 +08:00
    没有目标的优化,以及现状是什么情况,你这问题问了让人不知道怎么回答
    zhaokun
        27
    zhaokun  
       2023-09-13 21:25:25 +08:00
    不提量级谈何优化
    dayeye2006199
        28
    dayeye2006199  
       2023-09-14 06:49:18 +08:00 via Android
    听着是个无状态服务,那不是拿个 serverless function 胡一胡,爱多少并发就多少并发么
    fenglangjuxu
        29
    fenglangjuxu  
       2023-09-14 10:15:50 +08:00
    可以把 A 做成定时任务,先获取 token 存到 redis ,然后 b 服务从 redis 获取。如果 redis 没有获取到,实时再去获取一次。

    当然不知道 这个 token 是不是可以提前获取,是不是需要 b 的一些参数。
    left7410
        30
    left7410  
       2023-09-17 12:17:16 +08:00
    A 服务获取 token 可以用定时器获取,,然后把 token 存 redis ,然后看 B 服务接口是否支持批量操作,支持的话可以使用线程池批量去调 B 服务,不支持可以增加个 redis 存储 B 服务返回的数据,A 服务使用定时器异步批量处理。核心思想就是拆异步,加缓存,再不行就上集群吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1072 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 19:34 · PVG 03:34 · LAX 11:34 · JFK 14:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.