千万级入口服务[Gateway]框架设计(一)

news2024/11/17 7:28:09

本文将以技术调研模式编写,非技术同学可跳过。

文章目录

    • 背景
    • 问题[不涉及具体业务]
    • 目标
    • 技术选型
      • 语言
      • 框架模式
        • 实现一:go 原生组件
        • Demo 实现
        • Benchwork 基准性能
        • 小结
        • 实现二:开源 go-plugin
    • 附录
      • 入口服务演变

背景

在历史架构的迭代中,服务的入口级模块从雨后春笋到方兴未艾、以至于现在的如火如荼,最终成为服务定位中的,基础服务之一。

在这里插入图片描述
其核心功能一般是对流量进行清洗、漏斗、染色、追踪…等公共、通用性功能。

问题[不涉及具体业务]

现行的入口模块存在以下几个问题,急需进行改造、升级。

在这里插入图片描述

  • 框架过重
    • 框架控制单次请求中下游服务的调用模型
    • 框架显式支持串行调用,隐式支持并行调用
    • 框架嵌套基础组件SDK,部分功能为黑盒

目标

针对现行模块中暴露出的核心问题,从问题出发,推敲、构建预期框架模式特性。
在这里插入图片描述

  • 轻量
    • 收敛、抽象模块功能,解锁业务与框架之间的绑定、耦合
    • 提倡并行调用,串行辅助的调用策略
    • 承接云原生可观测组件,深度、全面刨析服务状态,杜绝黑盒、盲区
    • 支撑 兜底、降级…等必备手段

技术选型

语言

在这里插入图片描述

PHP 服务逐步迁移至 Goland,技术栈进行转换、升级。

框架模式

对于入口服务调度模块,随着下游业务的扩展,业务方的自定义需求会越来越多,越来越频繁。
为了能够让业务方自定义开发各自的业务逻辑,需要提供一种开发模式或者技术,能够由其他业务开发人员进行扩展,而不需重新编译整个模块的代码。(类似 Nginx 的模式,这也是中小企业,入口服务直接使用 代理 或者 Nginx 的原因)

在这里插入图片描述

考虑到插件模式可以帮助我们扩展原有程序的功能,同时它与原有工程是解耦的,可以独立开发,故小结如下:

  • 插件模式的核心功能/优势
    • 为系统提供灵活的扩展能力
      • 主服务 与 插件 的代码解耦,独立开发
      • 主服务 只关注插件的接口,不关注实现细
    • 不侵入系统现有功能
      • 主服务 动态引入插件,因而可以自由定制所需的能力,避免部署包的体积过大
      • 插件可以独立升级

实现一:go 原生组件

服务在执行过程中动态加载部分应用程序的能力(可能基于用户定义的配置)在某些设计中可能是一个有用的构建块。特别是,因为应用程序和动态加载的函数可以直接共享数据结构,所以插件可以实现独立部分的非常高性能的集成。
在这里插入图片描述

Go 附带一个内置于标准库中的插件包。这个包让我们编写的 Go 程序被编译成共享库而不是可执行二进制文件;此外,它还提供了用于加载共享库和从中获取符号的简单函数。

import (
	"plugin"
)

然而,插件机制有许多明显的缺点,在设计过程中应该仔细考虑。例如:

  • 插件目前仅在 Linux、FreeBSD 和 macOS 上受支持,因此它们不适合用于可移植的应用程序。
  • 使用插件的应用程序可能需要仔细配置,以确保程序的各个部分在文件系统(或容器映像)的正确位置可用。相比之下,部署由单个静态可执行文件组成的应用程序非常简单。
  • 当某些包可能在应用程序开始运行很长时间后才初始化时,关于程序初始化的推理会更加困难。
  • 攻击者可以利用加载插件的应用程序中的错误来加载危险或不受信任的库。
  • 除非程序的所有部分(应用程序及其所有插件)都使用完全相同版本的工具链、相同的构建标签以及某些标志和环境变量的相同值进行编译,否则很可能会发生运行时崩溃。

Demo 实现

实现分为三部分:主程序、组件程序、公共库。公共库可与主程序所属库共同,组件程序进行包引用即可。

  • 主程序
package main

import (
	"fmt"
	"os"
	"plugin"

	util "XXXX"
)

func main() {
	req := util.Req{Str: "A"}

	// 0. qt flow dispatch
	var mod string
	if mod = Dispatch(req.Str); len(mod) < 1 {
		fmt.Println("don't deal str")
		os.Exit(1)
	}
	// 1. open the so file to load the symbols
	plug, err := plugin.Open(mod)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	// 2. look up a symbol (an exported function or variable)
	symExecute, err := plug.Lookup("ModExecute")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	// 3. Assert that loaded symbol is of a desired type
	modExecute, ok := symExecute.(util.ModExecute)
	if !ok {
		fmt.Println("unexpected type from module symbol")
		os.Exit(1)
	}
	// 4. use the module
	modExecute.Init(&req)
	modExecute.Check()
	modExecute.Execute()
	res := modExecute.Out()
	fmt.Println("main run success res msg:", res.Msg)
}

func Dispatch(str string) string {
	var mod string
	switch str {
	case "A":
		mod = "./X/A.so"
	case "B":
		mod = "./X/B.so"
	default:
	}
	return mod
}

运行:go run main.go

  • 组件程序
package main

import (
	"fmt"

	util "XXXX"
)

type A struct {
}

func (s A) Init(req *util.Req) {
	fmt.Println("a module:Init:", req.Str)
}

func (s A) Check() {
	fmt.Println("a module:Check")
}

func (s A) Execute() {
	fmt.Println("a module:Execute")
}

func (s A) Out() util.Res {
	fmt.Println("a module:Out")
	return util.Res{Msg: "ok"}
}

var ModExecute A

运行: go build -buildmode=plugin -o X/A.so main-plugin.go

  • 公共库
package util

type ModExecute interface {
	Init(*Req) // 前置初始化操作
	Check()    // 流量签名&鉴权
	Execute()  // 执行操作
	Out() Res  // 输出
}

type Req struct {
	Str string
}

type Res struct {
	Msg string
}

Benchwork 基准性能

  • 基本性能十分优秀,32 核机器简单 Demo 基准性能测试
go test -bench BenchmarkMainDeal -benchtime=5s -benchmem
   87883             69740 ns/op            4998 B/op          6 allocs/op
PASS
ok      XXXXX  6.822s

小结

总之,这些限制意味着:在实践中,应用程序及其插件必须全部由一个人或系统的一个组件一起构建。在那种情况下,对于那个人或组件来说,生成空白导入所需插件集的 Go 源文件然后以通常的方式编译静态可执行文件可能更简单。

由于这些原因,许多用户认为传统的进程间通信 (IPC) 机制(例如套接字、管道、远程过程调用 (RPC)、共享内存映射或文件系统操作)可能更适合,尽管性能开销很大。

实现二:开源 go-plugin

相关 Demo 实现、Benchwork 基准性能、小结 见后续文章。


附录

  • https://eli.thegreenplace.net/2021/plugins-in-go/

入口服务演变

互联网初期的时候,是没有入口或前置服务的概念的。
请求服务都是从端上发起到后段处理的链路。随着业务种类及规模的膨胀,出现了以下的问题:

  • 端上承接大量的请求发起任务重担
  • 各业务接受请求后,都需要流量清洗、作弊判定…等公共处理举措
  • 网络带宽等资源数量级的增加
  • 用户体验对服务平响、数据质量…等性能要求的提升

基于这些棘手的问题,急需在服务入口提供一公共模块,进行一些前置操作,在节省资源、业务维护成本的同时,提升服务性能、质量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/642215.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch:部署 ELSER - Elastic Learned Sparse EncoderR

警告&#xff1a;此功能处于技术预览阶段&#xff0c;可能会在未来的版本中更改或删除。 Elastic 将尽最大努力修复任何问题&#xff0c;但技术预览中的功能不受官方 GA 功能的支持 SLA 约束。 Elastic Learned Sparse EncodeR - 或 ELSER - 是由 Elastic 训练的检索模型&#…

Python程序员必会技能:如何在Python中连接数据库获取数据

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 想要成为一名数据分析师&#xff0c;一个最基础的技能就是&#xff1a;提取数据。 数据是数据分析的基础。 因此&#xff0c;掌握各种获取数据的技能一定是一个合格的数据分析师的必备技能。 而我们的需要进行提取的…

总结排查服务器上传下载慢的几种手段与查看服务器带宽的具体方法

一、排查服务器上传下载 最近出现的一个情况&#xff0c;服务器上传和下载比较慢&#xff0c;因此我排查了种种手段&#xff0c;特此记录下几种常见的手段。 1、使用speedtest-cli 测试网速&#xff1a; 该方法是测试网速的速度怎么样&#xff0c;看看是否真的慢&#xff1f; …

python中os库用法详解(总结)

os库主要是对文件和文件夹进行操作&#xff0c;在Python中对⽂件和⽂件夹的操作要借助os模块⾥⾯的相关功能。 具体步骤如下&#xff1a; 1. 导⼊os模块 import os 2. 使⽤ os 模块相关功能 os.函数名() 1、⽂件重命名 os.rename(⽬标⽂件名, 新⽂件名) 示例代码&#…

使用Docker从0开始在Linuex部署springboot项目(图文并茂)

一、前言 在腾讯云新买的洁白如新的云服务器&#xff0c;想要使用docker去部署springboot项目&#xff0c;特此记录&#xff01; 二、安装jdk 参考博客&#xff1a;https://blog.csdn.net/weixin_45853881/article/details/123402891 2.1 检查jdk 直接在腾讯云平台登陆云服…

软件测试进阶知识 —— 自动化测试总结

自动化测试 自动化测试的定义&#xff1a;使用一种自动化测试工具来验证各种软件测试的需求&#xff0c;它包括测试活动的管理与实施、测试脚本的开发与执行。 自动化测试只是测试工作的一部分&#xff0c;是对手工测试的一种补充; 自动化测试绝不能代替手工测试;多数情况下&a…

怎样高效率备考PMP

一方面由于这些考试的知识&#xff0c;在准备考试前我们大部分很少接触&#xff0c;大部分人考试的目的也未必是感兴趣&#xff0c;更多是因为考试结果能给我们带来的收益。因此长时间的学习不熟悉甚至不感兴趣的很容易疲倦&#xff0c;这不像我们工作或生活中的一些技能&#…

怎样用U盘重装Win10系统?用U盘重装Win10系统教程

怎样用U盘重装Win10系统&#xff1f;有些新手用户在问怎样用U盘才能完成Win10系统的重装&#xff0c;这时候用户需要准备一个U盘、一个能够正常联网的电脑&#xff0c;然后按照以下分享的用U盘重装Win10系统教程操作&#xff0c;就能轻轻松松完成Win10系统的重装。 准备工作&am…

482576-74-9,Fmoc-Thr(Ac4Manα1-2Ac3Manα1-2Ac3Manα)-OH,肽链中可以糖基化的主要是Ser和Thr

【产品描述】 Fmoc-Thr(Ac4Manα1-2Ac3Manα1-2Ac3Manα)-OH&#xff08;CAS:482576-74-9&#xff09;中肽链中可以糖基化的主要是Ser和Thr&#xff0c;此外还有酪氨酸、羟赖氨酸和羟脯氨酸糖基化修饰的糖肽&#xff0c;链接的位点是这些残基侧链上的羟基氧原子。连接的糖为半乳…

Element常用组件之 表单组件 form

1. 建立form.vue <template><el-form ref"form" :model"form" label-width"80px"><el-form-item label"活动名称"><el-input v-model"form.name"></el-input></el-form-item><el-f…

Pandas的窗口函数rolling和expanding用法说明

Pandas的窗口函数rolling和expanding 1、rolling 移动窗口 rolling() 移动窗口函数&#xff0c;它可以与 mean、count、sum、median、std 等聚合函数一起使用。为了使用方便&#xff0c;Pandas 为移动函数定义了专门的方法聚合方法&#xff0c;比如 rolling_mean()、rolling_…

ArduPilot之H743自动PID调节

ArduPilot之H743自动PID调节 1. 源由2. 涉及参数2.1 AUTOTUNE_*2.2 RCx_OPTION 3. 自动校准3.1 预准备3.2 参数配置3.3 操作步骤 4. 实操&总结5. 参考资料6. 补充视频 1. 源由 ArduCopter可以自动通过算法来对PID进行调优&#xff0c;不过这里有个前提是模型噪声要比较少。…

Mysql数据库的初体验

数据库管理系统是一个由因相互关联的数据的集合和一组用访问这些数据的程序组成&#xff0c;这个数据集合通常称作数据库&#xff0c;其中包含了关于某个企业的信息。DBMS的主要目标就是提供一种可以方便高效的存取数据库信息的途径。 一、数据库的基本概念 1.数据库的组成 ①…

一文让你了解appium自动化的工作原理

目录 前言&#xff1a; 一、Appium加载的过程图解 二、初步认识appium工作过程 三、bootstrap介绍 四、所使用的技术 五、Capabilities 六、自我理解的工作原理 前言&#xff1a; Appium是一个流行的开源自动化测试框架&#xff0c;支持移动应用程序的自动化测试。 一…

Varnish开源HTTP反向代理缓存服务器

第三阶段基础 时 间&#xff1a;2023年6月13日 参加人&#xff1a;全班人员 内 容&#xff1a; Varnish 目录 Varnish 端口号&#xff1a;TCP/6081 TCP/6082 配置文件&#xff1a;/etc/varnish/default.vcl 安装部署&#xff1a; 测试功能&#xff1a; Varnish V…

6月14日晚 19:00公开课直播 | 入门必看:40min 掌握低代码基础功能

大家好&#xff0c;新一期「ONEIN 公开课」要和大家见面啦&#xff01; Onein 公开课介绍 Onein 公开课&#xff0c;是万应低代码开设的直播课堂&#xff0c;专注低代码领域&#xff0c;希望帮助每一位用户更好的使用万应低代码。 随着低代码的兴起&#xff0c;低代码这一名词…

从小白到大神之路之学习运维第39天---第三阶段---MongoDB非关系型数据库(概述、安装、设置管理员、简单操作、配置文件说明,备份和还原)

第三阶段基础 时 间&#xff1a;2023年6月13日 参加人&#xff1a;全班人员 内 容&#xff1a; 目录 MongoDB概述 端口号&#xff1a;TCP/27017 配置文件&#xff1a;/etc/mongod.conf MongoDb安装部署 MongoDB设置密码 MongoDB操作命令与说明 配置文件说明 备份操作 1. 热备…

chatgpt赋能python:Python怎么居中对齐

Python怎么居中对齐 在Python中&#xff0c;输出对齐是一项基本功能。当我们想要打印表格或美化输出时&#xff0c;居中对齐是一个常见的要求。本文将介绍如何使用Python进行居中对齐&#xff0c;以及一些相关的技术和应用。 如何居中对齐&#xff1f; 要在Python中实现居中…

TypeScript知识汇总

一、ts简介 1、什么是ts 2、ts增加了什么 二、TypeScript开发环境搭建 注&#xff1a;如果npm i运行报错&#xff0c;需要以管理员身份运行一次&#xff0c;以上主要就是tsc xxx.ts 三、ts的基本类型——ts相当于是给js可以指定类型 //number、string、boolean等常用类型&am…

[游戏开发][Unreal]项目启动

新建项目时会有 [项目名].uproject文件&#xff0c;鼠标右键该文件点击Switch Unreal Engine version 如果你的 [项目名].uproject文件是个纯白的图标&#xff0c;证明没有关联到Unreal&#xff0c;该怎么办呢 使用搜索工具搜UnrealVersionSelector.exe 或者直接去你的UE5安装目…