RPC与HTTP

15 阅读2分钟

当网站流量很小时通常采用单一应用架构,只需要一个应用将所有功能都部署在一起,以减少节点部署和成本;之后是ORM框架,大大简化增删改查的操作流程;访问量逐渐增大,应用拆分以提升效率,MVC(模式-视图-控制器)架构就是一种用于加速前端页面开发的架构;垂直应用增多,应用交互不可避免,将核心业务抽取出来,作为独立服务,逐渐形成稳定的服务中心,使前端应用能快速响应需求变化,就出现了分布式服务架构;为了提高管理效率,RPC(远程过程调用)框架用于提高业务复用及整合。

RPC服务治理框架有Dubbo、Spring Cloud等。

参考www.jianshu.com/p/15dbc8665… RPC,Remote Procedure Call Generally,RPC底层包括了代码生成、序列化、网络通讯等,主流的微服务框架也会提供服务治理相关的能力,比如服务发现、负载均衡、熔断等。

RPC服务转发HTTP

  1. Cookie问题的处理

idl文件中base字段可以自定义扩展内容,增加extra字段。另外,在请求内容中增加cookie的optional字段亦可。 a.HTTP请求一般通过cookie来进行登录态校验,这些字段在RPC请求中不存在 b.RPC接口需要对cookie校验来包装一个不同的返回结果 对cookie校验一般通过中间件 RPC接口需要提供特定的错误信息和错误码,并且让转发接口感知到

sessionkey = c.Cookie("sessionid_ss")
method := c2.Param("method")
params := map[string]interface{}{}
params[SessionKey] = sessionkey
err = json.Unmarshal([]byte(req), &params)
if err != nil{
    return nil, response.ParamError, defaultre
}
result, err := util.GenericCall(c, method, params)

cookie可以通过host自带的处理方式拿到,之后通过extra字段传到RPC服务进行校验,cookie校验通过中间件进行数据处理

  1. KiteX中间件数据拦截

在执行完整的业务逻辑前,先校验请求的身份和权限,若不符合身份校验,则拒绝请求。由于拦截对于所有请求都生效,因此使用反射调整字段,并作为中间件插入server是一个合适的选择。

func ModifyResponseWithErrCode(resp interface{}, code base.BaseResp ){
    rv := reflect.ValueOf(resp)
    //获取真实response
    success := rv.MethodByName("GetSuccess").Call(nil)[0]
    if success.IsNil() {
        success = reflect.New(success.Type().Elem())
    }
    //获取 baseResp
    baseresp := success.Elem().FiledByName("BaseResp")
    if baseResp.IsNil(){
        baseresp = reflect.New(baseResp.Type().Elem())
    }
    //SetBaseResp
    baseResp.Elem().FiledByName("StatusMessage").Set(reflect.ValueOf(code.StatusMessage))
    success.MethodNyName("SetBaseResp").Call([]reflect.Value{baseResp})
    rv.MethodByName("SetSuccess").Call([]reflect.Value{success})
}
//这样中间件还可用于熔断或降级场景:当某台特定实例/POD的QPS超过一千,可选择指定某些非核心RPC方法直接返回,进行降级逻辑。基于代码的降级方案可以把粒度控制到单容器的单方法,一定程度上可以有比Argos更好的控制效果