使用 MOSN 作为 HTTP 代理

简介

  • 该样例工程演示了如何配置使得MOSN作为标准Http协议的代理+ MOSN之间的协议是HTTP2
  • 为了演示方便,启动一个MOSN监听两个端口,一个转发Client的请求,一个收到请求以后转发给Server

其访问路径如下:
相当于一个HTTP代理

访问路径

准备

需要一个编译好的MOSN程序cd ${projectpath}/cmd/mosn/maingo build

  • 示例代码目录

${targetpath} = ${projectpath}/examples/codes/http-sample/

  • 将编译好的程序移动到示例代码目录

mv main ${targetpath}/cd ${targetpath}

目录结构

main // 编译完成的MOSN程序server.go // 模拟的Http Serverconfig.json

配置文件

{
	"servers":[
		{
			// 默认日志目录
			"default_log_path":"stdout",
			// 配置路由,可以配置多个路由,对应不同的
			"routers":[
				{
					//路由的名称
					"router_config_name":"server_router",
					//虚拟 host,一个虚拟的 host 可以对应N个真实的host
					"virtual_hosts":[{
						// 虚拟host名称
						"name":"serverHost",
						//DNS 域名,必须能跟 virtual_host 的 URL 匹配
						"domains": ["*"],
						//可以配置多个 路由
						"routers": [
							{
								//匹配所有的url请求
								"match":{"prefix":"/"},
								//对应的 cluster 匹配成功后会从 cluster_name 指定的 cluster 中获取 地址进行转发
								"route":{"cluster_name":"serverCluster"}
							}
						]
					}]
				},
				{   //参考 server 端的配置说明
					"router_config_name":"client_router",
					"virtual_hosts":[{
						"name":"clientHost",
						"domains": ["*"],
						"routers": [
							{
								"match":{"prefix":"/"},
								"route":{"cluster_name":"clientCluster"}
							}
						]
					}]

				}
			],
			"listeners":[
				{
					// serverListener 用于监听 Mosn的请求,进行转发
					"name":"serverListener",
					"address": "127.0.0.1:2046",
					"bind_port": true,
					"filter_chains": [{
						"filters": [
							{
								"type": "proxy",
								"config": {
									"downstream_protocol": "Http1",
									"upstream_protocol": "Http1",
									"router_config_name":"server_router"
								}
							}
						]
					}]
				},
				{
					// clientListener 用于监听应用的请求进行转发 (这里实际上是监听的浏览器的请求)
					"name":"clientListener",
					"address": "127.0.0.1:2045",
					"bind_port": true,
					"filter_chains": [{
						"filters": [
							{
								"type": "proxy",
								"config": {
									// 单个mosn流转,无需进行协议的转换,配置成一致就可以
									"downstream_protocol": "Http1",
									"upstream_protocol": "Http1",
									"router_config_name":"client_router"
								}
							}
						]
					}]
				}
			]
		}
	],
	"cluster_manager":{
		"clusters":[
			{
				"name":"serverCluster",
				"type": "SIMPLE",
				"lb_type": "LB_RANDOM",
				"max_request_per_conn": 1024,
				"conn_buffer_limit_bytes":32768,
				"hosts":[
					//地址是对应的 应用的服务地址
					{"address":"127.0.0.1:8080"}
				]
			},
			{
				"name": "clientCluster",
				"type": "SIMPLE",
				"lb_type": "LB_RANDOM",
				"max_request_per_conn": 1024,
				"conn_buffer_limit_bytes":32768,
				"hosts":[
					//地址是对应的server 监听的地址
					{"address":"127.0.0.1:2046"}
				]
			}
		]
	},
	"admin": {
		"address": {
			"socket_address": {
				"address": "0.0.0.0",
				"port_value": 34901
			}
		}
	}
}

运行说明

HTTP Server 代码

package main

import (
	"fmt"
	"net/http"
)
/**
 * 一个简单的HTTP服务
 */
func ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Printf("[UPSTREAM]receive request %s", r.URL)
	fmt.Println()

	w.Header().Set("Content-Type", "text/plain")

	fmt.Fprintf(w, "Method: %s\n", r.Method)
	fmt.Fprintf(w, "Protocol: %s\n", r.Proto)
	fmt.Fprintf(w, "Host: %s\n", r.Host)
	fmt.Fprintf(w, "RemoteAddr: %s\n", r.RemoteAddr)
	fmt.Fprintf(w, "RequestURI: %q\n", r.RequestURI)
	fmt.Fprintf(w, "URL: %#v\n", r.URL)
	fmt.Fprintf(w, "Body.ContentLength: %d (-1 means unknown)\n", r.ContentLength)
	fmt.Fprintf(w, "Close: %v (relevant for HTTP/1 only)\n", r.Close)
	fmt.Fprintf(w, "TLS: %#v\n", r.TLS)
	fmt.Fprintf(w, "\nHeaders:\n")

	r.Header.Write(w)

}

func main() {
	http.HandleFunc("/", ServeHTTP)
	http.ListenAndServe("127.0.0.1:8080", nil)
}

启动一个HTTP Server

go run server.go

启动MOSN

  • 使用config.json 运行非TLS加密的MOSN

./main start -c config.json

使用CURL进行验证

curl [http://127.0.0.1:2045/](http://127.0.0.1:2045/)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章