首页 > 作文

基于Go语言实现的简易api网关的示例代码

更新时间:2023-04-04 01:30:10 阅读: 评论:0

浏览器的请求去请求目标地址,然后获得结果它再发送给浏览器。对于go语言来说,实现转发只需要简单的一行代码即可实现,如下所示:

httputil.newsinglehostreverproxy(address)

基于此功能,进行简单包装,实现从远端admin管理中心获取需要转发的路由信息或者可以从本地配置文件中获取,实现动态转发。后续可以根据业务情况,可以实现如下功能:
开发接口,实现动态添加代理规则,进行转发

过滤不合法的接口接口限流统一日志记录…

代码如下:

package mainimport ("encoding/json""flag""fmt""github.com/gin-gonic/gin""io""io/ioutil""log""net/http""net/http/httputil""net/url""os""strings")type respond struct {success boolstatus  stringdata    []proxy}type proxy struct {remark        string //描述prefix        string //转发的前缀判断upstream      string //后端 nginx 地址或者ip地址rewriteprefix string //重写}var (infolog  *log.loggererrorlog *log.loggerproxymap = make(map[string]proxy))var adminurl = flag.string("adminurl", "", "admin的地址")var profile = flag.string("profile", "", "环境")var proxyfile = flag.string("proxyfile", "", "测试环境的数据")//日志初始化func initlog() {errfile, err := os.openfile("errors.log", os.o_create|os.o_wronly|os.o_append, 0666)infofile, err := os.openfile("info.log", os.o_create|os.o_wronly|os.o_append, 0666)if err != nil {log.fatalln("打开日志文件失败:", err)}infolog = log.new(io.multiwriter(os.stderr, infofile), "info:", log.lstdflags|log.lmicroconds|log.lshortfile)errorlog = log.new(io.multiwriter(os.stderr, errfile), "error:", log.lstdflags|log.lmicroconds|log.lshortfile)}func main() {router := gin.default() //创建一个routerflag.par()initlog()if *profile != "" {infolog.printf("加载远端数据: %s ", *adminurl)initproxylist()} el {infolog.printf("加载本地配置数据: %s", *proxyfile)loa双曲线虚轴dproxylistfromfile()}router.any("/*action", forward) //所有请求都会经过forward函数转发router.run(":8000")}func initproxylist() {resp, _ := http.get(*adminurl)if resp != nil && resp.statuscode == 200 {bytes, err := ioutil.readall(resp.body)defer resp.body.clo()if err != nil {fm无花果治疗痔疮的方法t.println("ioutil.readall err=", err)return}var respond responderr = json.unmarshal(bytes, &respond)if err != nil {fmt.println("json.unmarshal err=", err)return}proxylist := respond.datafor _, proxy 网上聊天:= range proxylist {//追加 反斜杠,为了动态匹配的时候 防止 /proxy/test  /proxy/test1 无法正确转发proxymap[proxy.prefix+"/"] = proxy}}}func forward(c *gin.context) {hostreverproxy(c.writer, c.request)}func hostreverproxy(w http.responwriter, r *http.request) {if r.requesturi == "/favicon.ico" {io.writestring(w, "request path error")return}//从内存里面获取转发的urlvar upstream = ""if value, ok := proxymap[r.requesturi]; ok {//如果转发的地址是 / 开头的,需要去掉if strings.hassuffix(value.upstream, "/") {upstream += strings.trimright(value.upstream, "/")} el {upstream += value.upstream}//如果首位不是/开头,则需要追加if !strings.hasprefix(value.rewriteprefix, "/") {upstream += "/" + value.rewriteprefix} el {upstream += value.rewriteprefix}//去掉开头r.url.path = strings.replaceall(r.url.path, r.requesturi, "")}// par the urlremote, err := url.par(upstream)infolog.printf("requesturi %s upstream %s remote %s", r.requesturi, ups整改方案怎么写tream, remote)if err != nil {panic(err)}r.url.host = remote.hostr.url.scheme = remote.schemer.header.t("x-forwarded-host", r.header.get("host"))r.host = remote.hosthttputil.newsinglehostreverproxy(remote).rvehttp(w, r)}func loadproxylistfromfile() {file, err := os.open(*proxyfile)if err != nil {errorlog.println("err:", err)}var respond respond// 创建json解码器decoder := json.newdecoder(file)err = decoder.decode(&respond)if err != nil {fmt.println("loadproxylistfromfile failed", err.error())}proxylist := respond.datafor _, proxy := range proxylist {proxymap[proxy.prefix+"/"] = proxy}}

proxy_data.json 格式如下:

{  "success":true,  "status": "ok",  "data": [    {      "remark": "测试环境",      "prefix": "/division",      "upstream": "http://test.xxxxx.cn/",      "rewriteprefix": "/api/division"    },    {      "remark": "测试环境1",      "prefix": "/division1",      "upstream": "http://test.xxxx.cn/",      "rewriteprefix": ""    },    {      "remark": "测试环境2",      "prefix": "/division3",      "upstream": "http://test.xxxxxx.cn/",      "rewriteprefix": "/api/division"    }  ]}

启动脚本

## 加载本地配置文件数据go run proxy_agent.zr是什么元素go -proxyfile ./proxy_data.json## 启动从配置中心获取数据go run proxy_agent.go -profile prod -adminurl http://localhost:3000/proxy/findall

到此这篇关于基于go语言实现的简易api网关的示例代码的文章就介绍到这了,更多相关go api网关 内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 01:29:44,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/7cdcec4481e88137c680d29ceec34742.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:基于Go语言实现的简易api网关的示例代码.doc

本文 PDF 下载地址:基于Go语言实现的简易api网关的示例代码.pdf

标签:地址   环境   数据   测试
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图