1
julyclyde 326 天前
改改设计试试:
前端 POST 过来的那个,和实际干活的服务应该拆分 实际干活的服务可以被内部调用 |
2
steelshadow39 OP @julyclyde #1 但内部调用实际干活的接口时,还是需要前端 POST 过来的参数
|
3
oldManNewThought 326 天前 via Android
环绕 aop 获取参数列表,取到后最好发 mq 。不影响接口性能
|
4
julyclyde 326 天前
@steelshadow39 那说明你的拆分边界错误吧?
|
5
julyclyde 326 天前
@steelshadow39
把实际干活的服务独立出来之后,它就是简单的参数输入、干活输出 至于参数怎么输入的,可以由多个调用方发过来,其中一个是原有的内部调用方,另一个是原来负责被 POST 的那一方 1+2 的模式 你原来的“内部需求也模拟一个 POST”是 1+1 的方式,我觉得边界错误 |
6
Avn 326 天前 1
持久化不一定「需要对请求中每个参数的字段做解析」,技术设计取决于对「管理模块」的重试功能的业务定位。
例如,如果「管理模块」的重试功能,定位成面向偏技术人员的接口调用记录,前端展示给管理人员的是一个包含服务名、接口地址、URL 参数、请求体、请求时间、响应体等字段的列表,然后有个重试按钮。那么持久化就要做到网关层,请求体不用解析直接用文本类型存 JSON 到表字段。重试的时候拿到请求的相关数据,构造 HTTP 请求发送出去。 如果「管理模块」的重试功能,定位成面向偏业务人员的业务请求记录,前端展示给管理人员的是一个包含订单号、卖方、买方、订单状态、订单金额、订单创建时间等字段的订单列表,然后有个扣款失败重新扣款、退款失败重新退款等等业务操作按钮。那么显然每个想要有重试功能的业务,都要有自己的前端页面,来展示自己的业务字段,相应的微服务也要自己解析相关的字段、持久化相关的数据、提供相关的重试接口,来完成自己的业务重试逻辑。 看你的描述很像是第一种面向技术人员的接口日志,这种情况不需要解析请求体,因为网关不关心请求体的含义,把日志记清楚、到时候能根据记录的信息把 HTTP 请求重新发一遍就好了。 |
7
orioleq 326 天前 via iPhone
不要用关系数据库,参数用 json 直接存
|
8
steelshadow39 OP @Avn #6 非常感谢,您提到的两种情况我都有涉及,请求体信息(接口地址,时间等)我是准备在网关层持久化的,以便后续审计。但我的业务不像您提到的:必须要有前端显示,它可以理解为一次任务,第一次的任务配置需要用户前端填写,后续的任务执行都可以使用同一套配置。所以任务执行需求和审计需求是否都能用“直接存储 JSON 请求体”的方式满足呢?
如果是的话,每次管理模块调用子模块,就先从库中获取 JSON 请求体,再构造请求调用子模块接口。我还想过另外一种方案:管理模块不直接构造请求调用子模块,而是告诉子模块接口请求参数的存储地址,由子模块自行获取参数执行任务。对于前者,子模块接口接收不同类型的 RequestBody ,比如登录接口接收 LoginBody ,注册接口接收 RegisterBody 。对于后者,子模块接口的接受类型就固定了,都是“参数信息存储地址”。除此之外,我目前还没有想到这两种方式在实际开发中的优劣。 |
9
SorcererXW 326 天前 1
看看 opentelemetry 那一套,比较标准化,直接打 log 或者把请求体 attch 到 trace 上,具体存储都有现成的 opentelemetry exportor 。
|
10
vance123 326 天前
从楼主的回复来看,似乎是通过存储 body 的方式来同时实现审计和回放的目的,一表两用,节省存储空间和编码逻辑。如果是这样,我的建议是:
不要这样做,A 是 A ,B 是 B 。审计可以通过打日志的方式实现,回放用到的参数另外存表 |
11
Hopetree 326 天前
存 json 不就不需要管结构了吗,而且你也说了做一次重复请求,那就是改都不用改,所以 json 就是最简单的
|
12
vance123 326 天前
别存 json ,如果接口参数变了怎么办?
|
13
steelshadow39 OP @vance123 我这里的意思是:审计和重放都可以使用存 JSON 这种方式来实现,不是一表两用。确实应该按你说的,分开用,毕竟日志审计和重放还有差别,重放的话,管理模块还需要知道重放哪一条参数,所以我认为重放参数的持久化还要和某些属性关联,比如用户。
|
14
steelshadow39 OP @vance123 接口参数变的话,就存一个新的请求信息吧,不对原来的做修改
|
15
thevita 326 天前
关键是这个 “如果后端需要主动调用这个接口执行一次相同的任务” 吧,这里初步看,应该是业务设计的问题,
op 这里纠结的就是 是在这里用某种通用技术实现一个 通用的“重放” 方案呢,还是各个业务自己搞 我是没看明白 管理模块 为什么要重放,倾向于认为设计错误 场景我其实也没完全搞明白,只能说下经验:不要把技术设计和业务设计放在一起做 |
16
thevita 326 天前 1
@thevita 我能想到比较像的场景 eg:
比如我们有一些业务动作,可以前端直接触发,也可以有个 scheduler ( cron 等)调度触发 我想一般的做法这些 “业务动作” 属于 ”业务层“,而前面的 rest api/ scheduler , 只是这个业务 对外暴露的两个”前端“,所以逻辑上,这两部分应该是完全分开的,只是这两者可能存在事实共享部分代码(比如数据结构等),那可以用一些具体的技术手段来解决,所以我认为应该是逻辑上先得分开,再考虑能不能共享部分代码(因为这两部解决的问题不一样,先理清业务关系,考虑共享代码,只是为了解决,这块领域知识的维护问题) |
17
steelshadow39 OP @thevita 我的需求和您提到的 schedule 定时任务很像,第一次用户手动配置,请求接口,执行扫描任务。然后会设定这个扫描任务定期执行一次,我纠结的就是每次执行如何获取第一次请求中的参数配置。
|
18
akira 326 天前
@steelshadow39 那你这个就是伪需求。 先保存 再执行。
|
19
kaelamiki 326 天前
建议 op 把原始需求提出来,避免 xy 问题
|
20
itfisher 326 天前 via iPhone 1
@steelshadow39
@steelshadow39 如果是要记录用户请求&后续定时任务捞请求重放,把请求 url 路径和 req 保存下来就好( aop 获取数据,走异步 mq 保存)。 //另外: 不过看你的描述,感觉你场景更像是用户配置规则参数,然后根据规则后端来跑任务。如果是这种场景的话,其实更好的交互是,用户只能操作规则变更。 然后后段再给一个用户触发规则的操作,这个操作是: [读取规则&执行规则] ,那么后端的定时任务,代码就也可以是: [读取规则&执行规则] ,这样子逻辑会更统一一些 |
21
xbo586 325 天前
个人理解。网关确实不应该掺杂多余业务逻辑,但是通过你的描述,只是类似于日志的功能,所以我认为在网关里做持久化是没问题的。至于数据结构问题,根据经验用 json 是最好的,也可以解决你的问题,毕竟你的请求数据结构也不清晰。然后就是你所讲的“对于后者,子模块接口的接受类型就固定了,都是“参数信息存储地址””,这种方案不可取,没必要在一个数据请求链条中增加一次接口信息的重复读。最后,我建议 20 楼的做法,将你所描述的扫描任务抽象成固定“规则”。
|
22
abcbuzhiming 325 天前
@steelshadow39
然后会设定这个扫描任务定期执行一次,我纠结的就是每次执行如何获取第一次请求中的参数配置 ======= 这个想法好奇怪啊,你的任务第一次如何执行的,后面就如何执行。何来不能复用第一次请求中的参数呢?参数用 json ,甚至用 queryStr 键值对都能完成这个任务啊 |