【Easylive】项目常见问题解答(自用&持续更新中…) 汇总版
easylive-cloud-interact | easylive-cloud-web |
---|---|
![]() | ![]() |
1. 不同服务(web和interact)之间的调用方式
调用流程
• 角色分工:
• easylive-cloud-web
:作为消费者(Consumer),通过Feign客户端(InteractClient
)声明对interact
服务的接口调用。
• easylive-cloud-interact
:作为提供者(Provider),通过VideoCommentApi
和UserActionApi
等类实现具体的内部API逻辑。
• 调用链路:
-
Feign客户端声明(Web服务):
@FeignClient(name = Constants.SERVER_NAME_INTERACT) public interface InteractClient {@RequestMapping(Constants.INNER_API_PREFIX + "/comment/delCommentByVideoId")void delCommentByVideoId(@RequestParam String videoId); }
◦ 通过
@FeignClient
注解绑定到interact
服务,接口方法映射到interact
服务的内部API路径(如/inner/comment/delCommentByVideoId
)。 -
内部API实现(Interact服务):
@RestController @RequestMapping(Constants.INNER_API_PREFIX + "/comment") public class VideoCommentApi {@RequestMapping("/delCommentByVideoId")public void delCommentByVideoId(@NotEmpty String videoId) {// 实际业务逻辑} }
◦ 提供者通过
@RestController
和@RequestMapping
暴露接口,路径与Feign客户端声明一致(如/inner/comment/delCommentByVideoId
)。 -
实际调用:
◦ Web服务通过注入InteractClient
实例,直接调用其方法(如interactClient.delCommentByVideoId(videoId)
),底层由Feign和Ribbon完成服务发现和HTTP请求转发。
关键设计
• 服务发现:Feign客户端通过name = Constants.SERVER_NAME_INTERACT
动态解析interact
服务的地址(依赖注册中心如Nacos)。
• 路径约定:双方通过Constants.INNER_API_PREFIX
(如/inner
)统一内部API前缀,确保接口匹配。
• 协议透明化:Feign屏蔽了HTTP调用的细节,开发者只需关注接口定义和业务逻辑。
2. GatewayGlobalRequestFilter
的作用与实现原理
核心功能
• 安全拦截:防止外部请求直接访问内部服务API,强制所有请求通过网关路由。
• 实现方式:通过检查请求路径是否包含内部API前缀(Constants.INNER_API_PREFIX
),若包含则抛出异常。
代码解析
@Component
public class GatewayGlobalRequestFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String rawPath = exchange.getRequest().getURI().getRawPath();if (rawPath.indexOf(Constants.INNER_API_PREFIX) != -1) {throw new BusinessException(ResponseCodeEnum.CODE_404); // 拦截直接访问内部API的请求}return chain.filter(exchange); // 放行非内部API请求}@Overridepublic int getOrder() {return 0; // 过滤器执行优先级(数值越小优先级越高)}
}
如何实现安全隔离?
-
路径标记:
• 所有内部API统一添加前缀(如/inner
),例如:◦ Interact服务的API路径:
/inner/comment/delCommentByVideoId
◦ Feign客户端路径:
@RequestMapping(Constants.INNER_API_PREFIX + "/comment/delCommentByVideoId")
-
网关路由配置:
• 外部请求只能访问网关暴露的公开路由(如/api/**
),网关再将请求转发到内部服务。• 内部服务之间的调用通过Feign完成,路径包含
/inner
,但不经过网关(直接服务间通信)。 -
过滤器拦截:
• 当外部用户直接请求http://interact-service/inner/comment/delCommentByVideoId
时:◦ 请求到达网关的
GatewayGlobalRequestFilter
,因路径包含/inner
,触发异常(返回404)。• 当网关转发公开API(如
/api/comment
)到内部服务时,路径不包含/inner
,过滤器放行。
为什么必须走网关?
• 统一入口:网关负责鉴权、限流、日志等公共逻辑。
• 隐藏内部细节:外部无法感知内部服务地址和API路径(如/inner
仅用于服务间调用)。
• 安全合规:避免内部接口暴露给公网,减少攻击面。
总结
问题 | 关键点 |
---|---|
服务间调用 | 通过Feign声明接口 + @InnerApi 路径约定 + 服务发现机制。 |
网关过滤器的安全隔离 | 路径标记(/inner ) + 全局过滤器拦截 + 网关路由配置,强制外部请求走统一入口。 |
这种设计既保证了微服务间的灵活调用,又通过网关层实现了安全的访问控制。
1. 不同服务之间(web和interact)是如何进行调用的?
想象一下,你的系统有两个“部门”:
• Web服务(easylive-cloud-web
):负责对外提供接口,比如用户访问的网页或APP请求。
• Interact服务(easylive-cloud-interact
):专门处理互动相关的逻辑,比如弹幕、评论、用户行为记录等。
它们是怎么“沟通”的呢?
✅ Web服务说:“Interact老哥,帮我删个评论呗!”
• Web服务里有个“外交官”(InteractClient
),专门负责和Interact服务对话。
• 这个外交官(@FeignClient
)知道Interact服务的名字(SERVER_NAME_INTERACT
),所以能准确找到它。
• 它按照约定好的“暗号”(/inner/comment/delCommentByVideoId
)发送请求。
✅ Interact服务收到请求后:“好的,我来处理!”
• Interact服务内部有个“业务员”(VideoCommentApi
),专门处理评论相关的事情。
• 它看到请求路径匹配(/inner/comment/delCommentByVideoId
),就执行删除逻辑。
整个过程就像:
- Web服务(前端)说:“我要删评论!”
- InteractClient(外交官):“我去找Interact服务!”
- Interact服务(后端):“收到,马上处理!”
- Web服务(前端):“搞定,用户满意!”
关键点:
• FeignClient 让Web服务能像调用本地方法一样调用Interact服务。
• /inner/
前缀 是内部API的“暗号”,只有服务之间知道,外部不能直接访问。
2. GatewayGlobalRequestFilter的作用?如何强制走网关?
问题:
如果外部用户直接访问 http://interact-service/inner/comment/delCommentByVideoId
,岂不是能绕过网关,直接调用内部服务?
✅ 解决方案:GatewayGlobalRequestFilter
(网关的“保安”)
它的工作方式:
-
检查每个请求:
• 用户访问http://interact-service/inner/comment/delCommentByVideoId
• 网关的“保安”一看路径有
/inner/
,立刻警觉:“这是内部API,不能直接访问!”• 直接返回 404(找不到),让用户以为这个接口不存在。
-
放行合法请求:
• 如果用户访问的是公开API(比如/api/comment
),网关会正常放行,并转发给对应服务。
为什么必须走网关?
• 安全:网关可以做鉴权、限流、日志记录,防止恶意请求。
• 隐藏内部细节:外部用户不知道内部服务怎么调用的,只能通过网关访问。
• 统一入口:所有请求都经过网关,方便管理(比如灰度发布、熔断降级)。
通俗理解:
• 网关 就像公司的前台,所有访客必须登记才能进。
• GatewayGlobalRequestFilter
是前台的“黑名单检查员”,看到“内部员工通道”(/inner/
)直接拦下:“外人不能进!”
• FeignClient 是公司内部电话,员工之间可以直接沟通,但外人打不进来。
总结
- 服务间调用:Web服务通过
FeignClient
像打电话一样调用Interact服务,路径用/inner/
标记。 - 网关安全:
GatewayGlobalRequestFilter
像“保安”,禁止外部直接访问/inner/
接口,必须走网关。
这样设计既灵活(服务间直接通信)又安全(外部必须走网关),你的系统既高效又稳健! 🚀
服务间调用的流程步骤
1. 角色分工
• easylive-cloud-web
(消费者)
• 有个“外交官”叫 InteractClient
(在 consumer
包下),专门负责和 interact
服务对话。
• 它知道 interact
服务的名字(SERVER_NAME_INTERACT
),并且定义了几个“暗号”(API路径),比如:
◦ `/inner/danmu/delDanmByVideoId`(删弹幕) ◦ `/inner/comment/delCommentByVideoId`(删评论) ◦ `/inner/userAction/getUserActionList`(查用户行为)
• easylive-cloud-interact
(提供者)
• 有个“业务员”叫 VideoCommentApi
(在 provider
包下),专门处理评论相关的事情。
• 还有个“业务员”叫 UserActionApi
,负责用户行为查询。
• 它们都认 /inner/
开头的请求,比如:
◦ `VideoCommentApi` 认 `/inner/comment/delCommentByVideoId` ◦ `UserActionApi` 认 `/inner/userAction/getUserActionList`
2. 调用流程(一步步走)
场景:Web服务需要删除某个视频的评论,怎么操作?
✅ 第1步:Web服务说:“我要删评论!”
• Web服务的某个业务代码(比如 VideoService
)调用了:
interactClient.delCommentByVideoId("video123");
(InteractClient
是 @FeignClient
,它会自动把方法调用变成HTTP请求)
✅ 第2步:FeignClient(外交官)发请求
• Feign 会:
- 找注册中心(比如Nacos)问:“
SERVER_NAME_INTERACT
这个服务在哪?” - 拿到真实地址(比如
http://192.168.1.100:8080
)。 - 按照约定,发送HTTP请求到:
POST http://192.168.1.100:8080/inner/comment/delCommentByVideoId?videoId=video123
✅ 第3步:Interact服务(业务员)处理请求
• 请求到达 interact
服务后,VideoCommentApi
说:“这个路径(/inner/comment/delCommentByVideoId
)归我管!”
• 它调用 videoCommentService.deleteByParam()
执行真正的删除逻辑。
✅ 第4步:返回结果
• 删除完成后,interact
服务返回成功(HTTP 200),Web服务收到响应,流程结束。
3. 关键点总结
-
FeignClient 是“自动HTTP工具”
• 你写个接口(InteractClient
),加个@FeignClient
,它就能自动发HTTP请求,不用你手动写RestTemplate
。 -
/inner/
是内部暗号
• 只有服务之间知道这个前缀,外部用户直接访问会被网关拦截(后面讲GatewayGlobalRequestFilter
的作用)。 -
服务发现(Nacos)
• Feign 依赖注册中心找到interact
服务的真实IP和端口,所以服务必须注册到同一个Nacos。