前言

对服务进行拆微的过程中,有以下问题需要考虑:

  1. 拆离前后,旧服务要继续保持可用性。不能出现通知业务下游全体修改调用方式。
  2. 拆离前后,代码低耦合。不能出现业务代码侵入。
  3. 拆离过程,可以按照【单个接口】【某组接口】进行分块拆离。
  4. 拆离过程可复制,简单,可复用.

最后,整个拆离过程,需要结合团队正在使用中的框架,进行综合考量。

本次方案的执行背景是,对 xxxapisrv内的业务服务,抽离出 leafsrv, 原xxxapisrv成为proxy。团队语言是go,框架为gin

期望效果

解决方案(19) 基于go-gin框架进行服务低成本迁移_github

接入前

r.POST("/bbb/aaa", auth, handler)
r.POST("/bbb/aaa2", auth, handler2)
r.POST("/bbb/aaa3", auth, handler3)

接入后

xxxproxy.POST("/bbb/aaa", auth, handler)
xxxproxy.POST("/bbb/aaa2", auth, handler2)
xxxproxy.POST("/bbb/aaa3", auth, handler3)

sdk

ginproxy v1.0.0

​https://github.com/fwhezfwhez/ginproxy.git​

proxysrv

package main

import (
"github.com/fwhezfwhez/ginproxy"
"github.com/gin-gonic/gin"
)

func main() {
r := gin.New()

leafsrv := ginproxy.Group(r, "http://localhost:8081")


leafsrv.GET("/leaf")
leafsrv.GET("/leaf/:id")
leafsrv.POST("/leaf")
leafsrv.DELETE("/leaf/:id")
leafsrv.PATCH("/leaf/:id")
leafsrv.PUT("/leaf/:id")

r.Run(":8080")
}

leafsrv

package main

import (
"fmt"
"github.com/gin-gonic/gin"
)

func main() {
r := gin.New()

r.GET("/leaf", auth, getLeafs)
r.GET("/leaf/:id", auth, getLeaf)
r.POST("/leaf", auth, addLeaf)
r.DELETE("/leaf/:id", auth, deleteLeaf)
r.PATCH("/leaf/:id", auth, updateLeafField)
r.PUT("/leaf/:id", auth, updateLeafAllFields)

r.Run(":8081")
}

func auth(c *gin.Context) {
fmt.Println("auth pass")
c.Next()
}

func getLeafs(c *gin.Context) {
fmt.Println("get leafs")
c.JSON(200, gin.H{
"errno": 0,
"data": []gin.H{},
})
}

func getLeaf(c *gin.Context) {
fmt.Println("get a leaf")
c.JSON(200, gin.H{
"errno": 0,
"data": gin.H{},
})
}

func addLeaf(c *gin.Context) {
fmt.Println("add a leaf")
c.JSON(200, gin.H{
"errno": 0,
"data": gin.H{},
})
}

func deleteLeaf(c *gin.Context) {
fmt.Println("delete a leaf")
c.JSON(200, gin.H{
"errno": 0,
})
}

func updateLeafAllFields(c *gin.Context) {
fmt.Println("update leaf all fields")
c.JSON(200, gin.H{
"errno": 0,
})
}

func updateLeafField(c *gin.Context) {
fmt.Println("update leaf some fields")
c.JSON(200, gin.H{
"errno": 0,
})
}