婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識(shí)庫 > nginx作grpc的反向代理踩坑總結(jié)

nginx作grpc的反向代理踩坑總結(jié)

熱門標(biāo)簽:威海人工外呼系統(tǒng)供應(yīng)商 撫順移動(dòng)400電話申請 貴陽教育行業(yè)電話外呼系統(tǒng) 藍(lán)點(diǎn)外呼系統(tǒng) 烏海智能電話機(jī)器人 寧夏房產(chǎn)智能外呼系統(tǒng)要多少錢 做外呼系統(tǒng)的公司違法嗎 400電話申請方案 在百度地圖標(biāo)注車輛

背景

眾所周知,nginx是一款高性能的web服務(wù)器,常用于負(fù)載均衡和反向代理。所謂的反向代理是和正向代理相對應(yīng),正向代理即我們常規(guī)意義上理解的“代理”:例如正常情況下在國內(nèi)是無法訪問google的,如果我們需要訪問,就需要通過一層代理去轉(zhuǎn)發(fā)。這個(gè)正向代理代理的是服務(wù)端(也就是google),而反向代理則相反,代理的是客戶端(也就是用戶),用戶的請求到達(dá)nginx后,nginx會(huì)代理用戶的請求向?qū)嶋H的后端服務(wù)發(fā)起請求,并將結(jié)果返回給用戶。

(圖片來自維基百科)

正向代理和反向代理實(shí)際上是站在用戶的角度來定義的,正向也就是代理用戶所要請求的服務(wù),而反向則是代理用戶向服務(wù)發(fā)起請求。兩者一個(gè)很重要的區(qū)別:

正向代理服務(wù)方不感知請求方,反向代理請求方不感知服務(wù)方。
思考一下上面的例子,你通過代理訪問google時(shí),google只能感知到請求來自代理服務(wù)器,而無法直接感知到你(當(dāng)然通過cookie等手段也可以追蹤到);而通過nginx反向代理時(shí),你是不感知請求具體被轉(zhuǎn)發(fā)到哪個(gè)后端服務(wù)器上的。

nginx最常被用于反向代理的場景就是我們所熟知的http協(xié)議,通過配置nginx.conf文件可以很簡單地定義一個(gè)反向代理規(guī)則:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen       80;
        server_name  localhost;

        
        location / {
            proxy_pass http://domain;
        }
    }
}

nginx從1.13.10以后就支持gRPC協(xié)議的反向代理,配置類似:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen       81 http2;
        server_name  localhost;

        
        location / {
            grpc_pass http://ip;
        }
    }
}

但是當(dāng)需求場景更加復(fù)雜的時(shí)候,就發(fā)現(xiàn)nginx的gRPC模塊實(shí)際上有很多坑,實(shí)現(xiàn)的能力不如http完整,當(dāng)套用http的解決方案時(shí)就會(huì)出現(xiàn)問題

場景

最開始我們的場景很簡單,通過gRPC協(xié)議實(shí)現(xiàn)一個(gè)簡單的C/S架構(gòu):

但這種單純的直連有些場景下是不可行的,例如client和server在兩個(gè)網(wǎng)絡(luò)環(huán)境下,彼此不相連通,那就無法通過簡單的gRPC連接訪問服務(wù)。一種解決辦法是通過中間的代理服務(wù)器轉(zhuǎn)發(fā),用上面說的nginx反向代理gRPC方法:

nginx proxy部署在兩個(gè)環(huán)境都能訪問的集群上,這樣就實(shí)現(xiàn)了跨網(wǎng)絡(luò)環(huán)境的gRPC訪問。隨之而來的問題是如何配置這個(gè)路由規(guī)則?注意我們最開始的gRPC的目標(biāo)節(jié)點(diǎn)都是清晰的,也就是server1和server2的ip地址,當(dāng)中間加了一層nginx proxy后,client發(fā)起的gRPC請求的對象都是nginx proxy的ip地址。那client與nginx建立連接后,nginx如何知道需要將請求轉(zhuǎn)發(fā)給server1還是server2呢?(這里server1和server2不是簡單的同一個(gè)服務(wù)的冗備部署,可能需要根據(jù)請求的屬性決定由誰響應(yīng),例如用戶id等,因此不能使用負(fù)載均衡隨機(jī)挑選一個(gè)響應(yīng)請求)

解決辦法

如果是http協(xié)議,那有很多實(shí)現(xiàn)方法:

通過路徑區(qū)分

請求將server的信息添加在path里,例如:/server1/service/method,然后nginx轉(zhuǎn)發(fā)請求的時(shí)候還原為原始的請求:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen       80;
        server_name  localhost;

        location ~ ^/server1/ {
            proxy_pass http://domain1/;
        }
        
        location ~ ^/server2/ {
            proxy_pass http://domain2/;
        }
    }
}

注意http://domain/最后的斜杠,如果沒有這個(gè)斜杠請求的路徑會(huì)是/server1/service/method,而服務(wù)端只能響應(yīng)/service/method的請求,這樣就會(huì)報(bào)404的錯(cuò)誤。

通過請求參數(shù)區(qū)分

也可以將server1的信息放在請求參數(shù)里:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen       80;
        server_name  localhost;

        location /service/method {
            if ($query_string ~ x_server=(.*)) {
                proxy_pass http://$1;
            }
        }
    }
}

但對于gRPC就沒這么簡單了,首先gRPC不支持URI的寫法,nginx轉(zhuǎn)發(fā)的請求會(huì)保留原來的path,無法在轉(zhuǎn)發(fā)的時(shí)候修改path,這意味著上述的第一種辦法不可行。其次gRPC是基于HTTP 2.0協(xié)議的,HTTP2沒有queryString這一概念,請求頭里有一項(xiàng):path代表請求的路徑,例如/service/method,而這一路徑是不能攜帶請求參數(shù)的,也就是:path不能寫為/service/method?server=server1。這意味著上述的第二種方法也不可行。

注意到HTTP2中請求頭:path是指定請求的路徑的,那我們直接修改:path不就行了嗎:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen       80 http2;
        server_name  localhost;

        location ~ ^/(.*)/service/.* {
            grpc_set_header :path /service/$2;
            grpc_pass http://$1;
        }
    }
}

但是實(shí)際驗(yàn)證表明這種方法也不可行,直接修改:path的請求頭會(huì)導(dǎo)致服務(wù)端報(bào)錯(cuò),一種可能的錯(cuò)誤如下:

rpc error: code = Unavailable desc = Bad Gateway: HTTP status code 502; transport: received the unexpected content-type "text/html"

抓包后發(fā)現(xiàn),grpc_set_header并沒有覆蓋:path的結(jié)果,而是新增了一項(xiàng)請求頭,相當(dāng)于請求header里存在兩個(gè):path,可能就是因?yàn)檫@個(gè)原因?qū)е路?wù)端報(bào)了502的錯(cuò)誤。

山窮水盡之際想起gRPC的metadata功能,我們可以在client端將server的信息存儲(chǔ)在metadata中,然后在nginx路由時(shí)根據(jù)metadata中server的信息轉(zhuǎn)發(fā)給對應(yīng)的后端服務(wù),這樣就實(shí)現(xiàn)了我們的需求。對于go語言,設(shè)置metadata需要實(shí)現(xiàn)PerRPCCredentials接口,然后在發(fā)起連接的時(shí)候傳入這個(gè)實(shí)現(xiàn)類的實(shí)例:

type extraMetadata struct {
    Ip string
}

func (c extraMetadata) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
    return map[string]string{
        "x-ip": c.Ip,
    }, nil
}

func (c extraMetadata) RequireTransportSecurity() bool {
    return false
}

func main(){
    ...
    // nginxProxy是nginx proxy的ip或域名地址
    var nginxProxy string
    // serverIp是根據(jù)請求屬性計(jì)算好的后端服務(wù)的ip
    var serverIp string
    con, err := grpc.Dial(nginxProxy, grpc.WithInsecure(),
        grpc.WithPerRPCCredentials(extraMetadata{Ip: serverIp}))
}

然后在nginx配置里根據(jù)這個(gè)metadata轉(zhuǎn)發(fā)到對應(yīng)的server:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen       80 http2;
        server_name  localhost;

        location ~ ^/service/.* {
            grpc_pass grpc://$http_x_ip:8200;
        }
    }
}

注意這里使用了$http_x_ip這一語法引用了我們傳遞的x-ip這個(gè)metadata信息。這一方法驗(yàn)證有效,client可以通過nginx proxy成功訪問到server的gRPC服務(wù)。

總結(jié)

nginx的gRPC模塊的文檔太少了,官方文檔只給出了幾個(gè)指令的用途,并沒有說明metadata這一方法,網(wǎng)上的文檔也鮮有涉及,導(dǎo)致花了兩三天的時(shí)間在排查。將整個(gè)過程總結(jié)在這里,希望能幫助到遇到同一問題的人。

到此這篇關(guān)于nginx作grpc的反向代理踩坑總結(jié)的文章就介紹到這了,更多相關(guān)nginx grpc反向代理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

標(biāo)簽:周口 銅川 松原 泰州 慶陽 蕪湖 那曲 朝陽

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《nginx作grpc的反向代理踩坑總結(jié)》,本文關(guān)鍵詞  nginx,作,grpc,的,反向,代理,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《nginx作grpc的反向代理踩坑總結(jié)》相關(guān)的同類信息!
  • 本頁收集關(guān)于nginx作grpc的反向代理踩坑總結(jié)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    欧美亚洲动漫制服丝袜| www.亚洲色图| 椎名由奈av一区二区三区| 国产精品女主播av| **网站欧美大片在线观看| 亚洲精品中文字幕在线观看| 同产精品九九九| 国产在线精品一区二区| av不卡一区二区三区| 在线视频你懂得一区二区三区| 欧美日韩免费观看一区三区| 日韩免费观看2025年上映的电影| 久久久久久久久伊人| 综合久久给合久久狠狠狠97色 | 欧美一级视频精品观看| 亚洲精品在线电影| 亚洲最快最全在线视频| 国产乱子轮精品视频| 色欧美乱欧美15图片| 欧美精品一区男女天堂| 亚洲一区二区三区四区五区黄| 久久精品国产色蜜蜜麻豆| 成人av在线网| 精品国产三级电影在线观看| 中文字幕一区二区三区乱码在线 | 国产精品狼人久久影院观看方式| 伊人开心综合网| 国产高清精品网站| 在线不卡中文字幕播放| 中文字幕一区二区在线观看| 久久精品国产在热久久| 欧美午夜精品久久久| 国产午夜精品美女毛片视频| 午夜精品久久久久影视| 成人福利视频在线看| 日韩一区二区在线看片| 亚洲一区二区三区四区在线| av一二三不卡影片| 久久久精品国产99久久精品芒果 | 成人午夜电影久久影院| 精品国产乱码久久久久久免费 | 在线一区二区三区四区五区| 国产欧美精品一区| 久久黄色级2电影| 91精品国产综合久久久久| 亚洲视频免费看| www.激情成人| 国产精品美女久久福利网站| 国产电影一区二区三区| 精品国产区一区| 久久99精品久久久久久久久久久久 | 久久99久久99小草精品免视看| 欧美色男人天堂| 亚洲午夜一区二区三区| 国产 日韩 欧美大片| 久久精品在这里| 国产精品一区二区免费不卡| 日韩免费电影网站| 蜜臀av一区二区在线观看| 5月丁香婷婷综合| 奇米精品一区二区三区在线观看| 色综合色狠狠综合色| 亚洲欧美国产77777| 色婷婷精品久久二区二区蜜臀av| 中文字幕日韩av资源站| 97久久久精品综合88久久| 综合av第一页| 在线视频欧美精品| 午夜私人影院久久久久| 欧美日韩国产美女| 免费看精品久久片| 精品999在线播放| 成人精品视频一区| 亚洲老司机在线| 欧美日本在线观看| 蜜桃av一区二区三区电影| 久久综合五月天婷婷伊人| 国产乱一区二区| 亚洲色图在线视频| 欧美日韩在线观看一区二区| 蜜桃视频在线观看一区| 国产日韩亚洲欧美综合| 色哟哟精品一区| 日韩精品电影在线| 久久精品一区二区三区不卡| 色综合激情五月| 日韩国产精品大片| 国产农村妇女毛片精品久久麻豆 | 欧美电影精品一区二区| 国产一区二区三区蝌蚪| 久久精品人人做人人综合 | 日韩精品乱码免费| 久久夜色精品国产欧美乱极品| 日本亚洲欧美天堂免费| 色婷婷av一区二区三区大白胸| 久久影院电视剧免费观看| 精品一区二区三区在线播放视频| 欧美日免费三级在线| 偷窥少妇高潮呻吟av久久免费| 日韩美女天天操| 欧美一区二区福利在线| 国产美女精品人人做人人爽| 亚洲精品成a人| 久久你懂得1024| 欧洲一区二区av| 国产呦萝稀缺另类资源| 亚洲永久免费视频| 精品国产91洋老外米糕| 一本到一区二区三区| 激情av综合网| 天天做天天摸天天爽国产一区| 欧美国产日产图区| 日韩视频一区二区三区| 色综合久久综合中文综合网| 久久99精品久久久久久动态图| 一区二区三区日韩欧美精品| 久久精品在这里| 日韩免费一区二区三区在线播放| 欧美亚洲愉拍一区二区| 九色综合狠狠综合久久| 亚洲人吸女人奶水| 国产人成一区二区三区影院| 欧洲一区在线电影| 91丨九色丨蝌蚪丨老版| 国产二区国产一区在线观看| 麻豆91小视频| 一区二区三区影院| 亚洲欧美一区二区视频| 26uuu精品一区二区在线观看| 欧美在线不卡视频| 91在线视频观看| 国产在线视频精品一区| 日韩国产精品大片| 亚洲成人免费观看| 中文久久乱码一区二区| 久久综合999| 精品日韩99亚洲| 91精品国产综合久久精品麻豆 | 91麻豆swag| 波多野洁衣一区| 成人免费av在线| 豆国产96在线|亚洲| 国产一区美女在线| 久久99热国产| 国产乱码精品1区2区3区| 国产在线播精品第三| 精品一区二区av| 国产精品系列在线播放| 国产一区二区在线观看免费| 国产一区二区三区国产| 国产精品一区二区久激情瑜伽| 国精品**一区二区三区在线蜜桃| 人人狠狠综合久久亚洲| 麻豆国产精品777777在线| 美国十次综合导航| 日本vs亚洲vs韩国一区三区| 免费观看在线综合色| 美女在线一区二区| 精品无人码麻豆乱码1区2区| 国产一区二区在线看| 国产电影一区在线| 99久久免费国产| 91高清视频免费看| 91麻豆精品国产91久久久久久久久| 欧美精品黑人性xxxx| 欧美电影精品一区二区 | 久久99蜜桃精品| 国产制服丝袜一区| 99re6这里只有精品视频在线观看| 91麻豆.com| 欧美精品三级在线观看| 欧美电影免费观看高清完整版| 国产亚洲精品免费| 一区二区在线观看免费视频播放| 亚洲成人动漫在线观看| 老司机一区二区| 成人国产精品免费| 欧美日韩一级黄| www国产精品av| 亚洲欧美日韩一区| 日韩av成人高清| 国产高清不卡一区二区| 欧美在线你懂得| 精品久久久久香蕉网| 亚洲女爱视频在线| 久久99精品久久久久久国产越南| 成人国产精品免费| 日韩精品中午字幕| 亚洲三级理论片| 久久成人av少妇免费| 粉嫩av亚洲一区二区图片| 欧美性大战久久久久久久蜜臀 | 在线观看免费成人| 欧美电视剧免费全集观看| 综合久久给合久久狠狠狠97色| 免费观看一级特黄欧美大片| 99精品视频在线播放观看| 日韩一级精品视频在线观看| 亚洲天堂av老司机| 国产成人精品免费视频网站|