【微服务网关——https与http2代理实现】
1.https与http2代理
1.1 重新认识https与http2
- https是http安全版本
- http2是一种传输协议
- 两者并没有本质联系
1.1.1 https与http的区别
HTTP(超文本传输协议)和 HTTPS(安全超文本传输协议)是用于在网络上交换数据的两种协议。HTTPS 是 HTTP 的扩展,它在 HTTP 的基础上增加了加密层SSL/TLS ,以保护数据的安全。
- HTTPS
- 加密: HTTPS 使用 SSL/TLS 协议来加密传输的数据,保护数据免受窃听。
- 验证身份: HTTPS 通过数字证书验证服务器的身份,确保数据被发送到正确的服务器。
- 数据完整性: HTTPS 通过加密和校验机制,确保传输的数据不会被篡改。
- 端口:443
https请求流程
1.1.2 http1.1与http2区别
- HTTP/1.1
- 文本协议:数据以明文格式传输,HTTP/1.1 请求和响应是人类可读的文本。
- 单一请求-响应通道:每次请求和响应通过单独的 TCP 连接传输,连接复用有限。
- 队头阻塞:由于请求是按顺序处理的,前一个请求处理未完成时,后续请求会被阻塞。
- 连接管理:需要为每个请求创建一个新的连接,或者使用连接保持(keep-alive)来重用连接。
- HTTP/2
- 二进制协议:数据以二进制格式传输,增加了解析和处理的效率。
- 多路复用:一个 TCP 连接可以同时承载多个请求和响应,消除了队头阻塞(Head-of-Line Blocking)的问题。
- 头部压缩:使用 HPACK 算法对 HTTP 头部进行压缩,减少了冗余数据的传输。
- 优先级控制:可以设置请求的优先级,优化资源的分配和加载顺序。
1.2 http2与https的关系
- http2代表多路复用的传输协议
- https代表http服务器使用了加密协议
- 一个启用https的服务器不一定使用http2
- 但是使用http2的服务器必须启用https(浏览器强制)
1.3 http2设计目标
- 感知延迟有实质上改进
- 解决HTTP1.1中的“队首阻塞”问题
- 并行操作无需与服务器建立多个连接
- 保持HTTP1.1语义,只是标准拓展并非替代
2.https与http2代理实现
2.1 创建下游测试服务器
2.1.1 代码实现
package mainimport ("fmt""github.com/e421083458/gateway_demo/demo/proxy/reverse_proxy_https/testdata""golang.org/x/net/http2""io""log""net/http""os""os/signal""syscall""time"
)
func main() {rs1 := &RealServer{Addr: "127.0.0.1:3003"}rs1.Run()rs2 := &RealServer{Addr: "127.0.0.1:3004"}rs2.Run()//监听关闭信号quit := make(chan os.Signal)signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)<-quit
}type RealServer struct {Addr string
}func (r *RealServer) Run() {log.Println("Starting httpserver at " + r.Addr)mux := http.NewServeMux()mux.HandleFunc("/", r.HelloHandler)mux.HandleFunc("/base/error", r.ErrorHandler)server := &http.Server{Addr: r.Addr,WriteTimeout: time.Second * 3,Handler: mux,}go func() {// 开启http2http2.ConfigureServer(server, &http2.Server{})// 开启httpslog.Fatal(server.ListenAndServeTLS(testdata.Path("server.crt"), testdata.Path("server.key")))}()
}func (r *RealServer) HelloHandler(w http.ResponseWriter, req *http.Request) {upath := fmt.Sprintf("http://%s%s\n", r.Addr, req.URL.Path)io.WriteString(w, upath)
}func (r *RealServer) ErrorHandler(w http.ResponseWriter, req *http.Request) {upath := "error handler"w.WriteHeader(500)io.WriteString(w, upath)
}
2.1.2 证书签名生成方式
/*
//CA私钥
openssl genrsa -out ca.key 2048
//CA数据证书
openssl req -x509 -new -nodes -key ca.key -subj "/CN=example1.com" -days 5000 -out ca.crt//服务器私钥(默认由CA签发)
openssl genrsa -out server.key 2048
//服务器证书签名请求:Certificate Sign Request,简称csr(example1.com代表你的域名)
openssl req -new -key server.key -subj "/CN=example1.com" -out server.csr
//上面2个文件生成服务器证书(days代表有效期)
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000
*/
2.1.3 如何开启http2
goLang服务器支持https与http
- ListenAndServer调整成ListenAndServerTLS即可支持https
- https服务器设置http2.ConfigureServer支持http2
- 设置http2对应的handler回调
- http.Server中设置了对http2的回调
- http2回调方法负责从帧数据流中转换数据为http请求体
// ConfigureServer 为 net/http 的 Server 添加 HTTP/2 支持。
//
// 参数 conf 可以为 nil。
//
// ConfigureServer 必须在 s 开始服务之前调用。
func ConfigureServer(s *http.Server, conf *Server) error {if s == nil {panic("nil *http.Server") // 如果传入的 *http.Server 是 nil,程序会崩溃}if conf == nil {conf = new(Server) // 如果传入的 Server 配置是 nil,则新建一个默认的 Server 配置}// 初始化 conf 的内部状态conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}// 如果 conf 中的 IdleTimeout 没有设置,则使用 s 的 IdleTimeout 或 ReadTimeoutif h1, h2 := s, conf; h2.IdleTimeout == 0 {if h1.IdleTimeout != 0 {h2.IdleTimeout = h1.IdleTimeout} else {h2.IdleTimeout = h1.ReadTimeout}}// 注册优雅关机的回调函数s.RegisterOnShutdown(conf.state.startGracefulShutdown)// 如果没有 TLS 配置,创建一个默认的 TLS 配置if s.TLSConfig == nil {s.TLSConfig = new(tls.Config)} else if s.TLSConfig.CipherSuites != nil {// 如果已提供了 CipherSuite 列表,检查它的顺序或是否缺少必要的 CipherSuitehaveRequired := falsesawBad := falsefor i, cs := range s.TLSConfig.CipherSuites {switch cs {case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,// 另一种 MTI 密码套件,防止只支持 ECDSA 的服务器。// 详情请参见 http://golang.org/cl/30721。tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:haveRequired = true}if isBadCipher(cs) {sawBad = true} else if sawBad {return fmt.Errorf("http2: TLSConfig.CipherSuites 索引 %d 包含 HTTP/2 批准的密码套件 (%#04x),但它在未批准的密码套件之后。这样配置,可能会导致不支持先前批准的密码套件的客户端被分配一个未批准的套件并拒绝连接。", i, cs)}}if !haveRequired {return fmt.Errorf("http2: TLSConfig.CipherSuites 缺少 HTTP/2 所需的 AES_128_GCM_SHA256 密码(至少需要 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 或 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 之一)。")}}// 注意:这里没有设置 MinVersion 为 tls.VersionTLS12,// 因为我们不想干扰用户服务器上的 HTTP/1.1 流量。我们稍后在接受连接时强制执行 TLS 1.2。// 理想情况下,这应该在下一步协议选择中完成,但使用 TLS <1.2 与 HTTP/2 仍然是客户端的错误。s.TLSConfig.PreferServerCipherSuites = true // 服务器优先选择密码套件haveNPN := falsefor _, p := range s.TLSConfig.NextProtos {if p == NextProtoTLS {haveNPN = truebreak}}if !haveNPN {s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS) // 添加 HTTP/2 协议}if s.TLSNextProto == nil {s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){} // 初始化 TLSNextProto 映射}// 定义 protoHandler,用于处理新连接protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) {if testHookOnConn != nil {testHookOnConn() // 测试钩子,如果存在,则调用}// TLSNextProto 接口早于 context 出现,因此 net/http 包通过 Handler 上一个未公开的方法传递每个连接的基础 context。// 这仅供内部 net/http<=>http2 使用。var ctx context.Contexttype baseContexter interface {BaseContext() context.Context}if bc, ok := h.(baseContexter); ok {ctx = bc.BaseContext() // 获取 base context}// 服务连接conf.ServeConn(c, &ServeConnOpts{Context: ctx,Handler: h,BaseConfig: hs,})}s.TLSNextProto[NextProtoTLS] = protoHandler // 设置 protoHandlerreturn nil // 成功返回 nil
}
2.2 https代理整合网关
package publicimport ("crypto/tls""crypto/x509""fmt""github.com/e421083458/gateway_demo/demo/proxy/reverse_proxy_https/testdata""golang.org/x/net/http2""io/ioutil""math/rand""net""net/http""net/http/httputil""net/url""strings""time"
)var transport = &http.Transport{DialContext: (&net.Dialer{Timeout: 30 * time.Second, //连接超时KeepAlive: 30 * time.Second, //长连接超时时间}).DialContext,//TLSClientConfig: &tls.Config{InsecureSkipVerify: true},TLSClientConfig: func() *tls.Config {pool := x509.NewCertPool()caCertPath := testdata.Path("ca.crt")caCrt, _ := ioutil.ReadFile(caCertPath)pool.AppendCertsFromPEM(caCrt)return &tls.Config{RootCAs: pool}}(),MaxIdleConns: 100, //最大空闲连接IdleConnTimeout: 90 * time.Second, //空闲超时时间TLSHandshakeTimeout: 10 * time.Second, //tls握手超时时间ExpectContinueTimeout: 1 * time.Second, //100-continue 超时时间
}func NewMultipleHostsReverseProxy(targets []*url.URL) *httputil.ReverseProxy {//请求协调者director := func(req *http.Request) {targetIndex := rand.Intn(len(targets))target := targets[targetIndex]targetQuery := target.RawQueryfmt.Println("target.Scheme")fmt.Println(target.Scheme)req.URL.Scheme = target.Schemereq.URL.Host = target.Hostreq.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)if targetQuery == "" || req.URL.RawQuery == "" {req.URL.RawQuery = targetQuery + req.URL.RawQuery} else {req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery}if _, ok := req.Header["User-Agent"]; !ok {req.Header.Set("User-Agent", "user-agent")}}http2.ConfigureTransport(transport)return &httputil.ReverseProxy{Director: director, Transport: transport,}
}func singleJoiningSlash(a, b string) string {aslash := strings.HasSuffix(a, "/")bslash := strings.HasPrefix(b, "/")switch {case aslash && bslash:return a + b[1:]case !aslash && !bslash:return a + "/" + b}return a + b
}
相关文章:

【微服务网关——https与http2代理实现】
1.https与http2代理 1.1 重新认识https与http2 https是http安全版本http2是一种传输协议两者并没有本质联系 1.1.1 https与http的区别 HTTP(超文本传输协议)和 HTTPS(安全超文本传输协议)是用于在网络上交换数据的两种协议。H…...

mssql查询历史执行过的语句日志
SELECT deqs.creation_time,dest.text AS [SQL Text],deqs.execution_count,deqs.total_elapsed_time,deqs.total_worker_time FROM sys.dm_exec_query_stats AS deqs CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest--where dest.text like %这个是我的条件&#…...
【LeetCode】每日一题:买卖股票的最佳时机 II
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。 在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。 返回 你能获得的 最大 利润 。 AC代码 水…...

【TS】TypeScript 联合类型详解:解锁更灵活的类型系统
🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 TypeScript 联合类型详解:解锁更灵活的类型系统一、联合类型的定义二…...

kali改回官方源后更新失败
官方源: deb http://http.kali.org/kali kali-rolling main non-free contrib deb-src http://http.kali.org/kali kali-rolling main non-free contrib在文件 /etc/cat/sources.list中将官方源修改为: deb http://http.kali.org/kali kali-rolling ma…...
Mysql 左关联(LEFT JOIN)
在左关联(LEFT JOIN)操作中,关于大表和小表的连接顺序,通常建议将小表放在前面,大表放在后面。这种安排方式有助于提高查询效率,原因如下: 扫描效率:在SQL查询中,尤其是…...
[笔记]小米CyberDog机器狗仿真调试记录
从官方github的所有源码库来看,所有的source命令只有两条,执行它以配置环境变量: source /opt/ros/galactic/setup.bash source /home/cyberdog_ws/install/setup.bash 如果运行脚本之后gazebo正常启动及机器狗模型在悬空状态,问…...

第十四届蓝桥杯省赛C++B组G题【子串简写】题解(AC)
题目大意 给定字符串 s s s,字符 a , b a, b a,b,问字符串 s s s 中有多少个 a a a 开头 b b b 结尾的子串。 解题思路 20pts 使用二重循环枚举左端点和右端点,判断是否为 a a a 开头 b b b 结尾的字符串,是则答案加一…...
实现Java Web应用的高性能负载均衡方案
实现Java Web应用的高性能负载均衡方案 大家好,我是微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 在高并发的网络环境中,负载均衡是确保Web应用程序高性能和可靠性的关键策略之一。本文将探讨如何…...
医学预测模型web APP的制作建议
医学预测模型web APP的制作建议 医学预测模型类web APP定义为承载预测模型而便利预测模型临床应用的可视化客户端。 医学预测模型类web APP的功能是衔接预测模型和临床实践,让用户正确地,方便地使用预测模型并恰当地理解预测模型的结果,在此…...
gitlab每日备份以及restore
gitlab服务有非常简洁的每日备份命令, 从production的gitlab的每日备份中restore到backup环境也非常方便。 一、Production gitlab每日备份 1. Production gitlab环境上编写脚本 cat /root/gitlab_bak.shgitlab-rake gitlab:backup:create > /var/opt/gitl…...

2024-07-05 base SAS programming学习笔记9(variables)
1.在数据集增加累加变量值(SUM) 求和语句(SUM STATEMENT):variableexpression variable是累积求和的变量名,为数值型,默认初始值为0;该variable值则会保留到一个观测 当expression有缺失值,在求…...

kafka--发布-订阅消息系统
1. Kafka概述 1. kafka是什么 kafka是分布式的、高并发的、基于发布/订阅模式的消息队列软件系统。 kafka中的重要组件 Producer:消息生产者,发布消息到Kafka集群的终端或服务Consume:消费者,从Kafka集群中消费消息的终端或服…...
2024最新软件测试面试题。内附答案+文档
🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 1、你以前工作时的测试流程是什么? 参考答案:(灵活回答&…...

新加坡很火的slots游戏代投Facebook广告新流量趋势
新加坡很火的slots游戏代投Facebook广告新流量趋势 在新加坡这片充满活力的土地上,Slots游戏以其独特的魅力和吸引力,迅速成为了许多玩家的心头好。而Facebook,作为全球最大的社交媒体平台之一,为Slots游戏的推广提供了得天独厚的…...
C++ 实现字符串逆序
C 实现字符串逆序 思路: 输入一个字符串。使用双指针法,交换字符串的首尾字符,逐步向中间移动。输出逆序后的字符串。 #include <iostream> #include <string>using namespace std;void reverseString(string &str) {int …...

【项目实践】贪吃蛇
一、游戏效果展示二、博客目标三、使用到的知识四、Win32 API 介绍 4.1 WIn32 API4.2 控制台程序4.3 控制屏幕上的坐标COORD4.4 GetStdHandle4.5 GetConsoleCursorInfo 4.5.1 CONSOLE_CURSOR_INFO 4.6 SetConsoleCursorInfo4.7 SetConsoleCursorPosition4.8 GetAsyncKeyState 五…...

将exe文件添加到注册表中,实现开机时自动运行
目录 一、前言 二、代码 三、使用步骤 1.编译生成exe文件、 2.以管理员身份运行代码 3.打开注册表,验证结果 一、前言 在Windows操作系统中,将exe文件的路径添加到注册表下,主要用于实现程序的开机自动运行功能。 注册表路径为…...
SQL使用注意事项
作为开发人员日常最为熟悉的工具sql。但是在实际使用中,有一些坑需要尽量避免,本文是对一些常用注意事项的总结 查询需要的。不要全部都查询。禁止使用存储过程,禁止使用外键。使用sql进行计算,要小心。(数据量大的情况…...
uniapp小程序IOS端,uni.createInnerAudioContext()无声音
可能的问题 路径中有中文字符需要使用uni.getBackgroundAudioManager()播放其他问题 解决办法 首先我的路径中没有中文字符,如果有的,可能需要转义一下或者干脆不使用中文字符,第二个也是从其他博客中看到的,我这边分享一下我的…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...