当前位置: 首页 > news >正文

网站做第三方登录界面/网络推广外包内容

网站做第三方登录界面,网络推广外包内容,温州logo设计公司,折扣手游平台app排行榜本题分别从如下三个方面来分享: 问题描述 自定义连接池的编写 common_pool 的使用 问题描述 线上有一个业务,某个通服务通知 udp 客户端通过向 udp 服务端(某个硬件设备)发送 udp 包来进行用户上线操作 当同时有大量的请求打到…

本题分别从如下三个方面来分享:

  • 问题描述
  • 自定义连接池的编写
  • common_pool 的使用

问题描述

线上有一个业务,某个通服务通知 udp 客户端通过向 udp 服务端(某个硬件设备)发送 udp 包来进行用户上线操作

当同时有大量的请求打到 udp 服务端的时候,udp 服务端的回包可能会在网络环境中丢包,(udp 是不可靠的)导致 udp 客户端不能及时的收到 udp 服务端的回包,在短时间内,udp 客户端的句柄又没有得到复用或者释放,没有收到回包的句柄就一直阻塞在那里,最终导致句柄泄漏

那么可以如何解决呢?

  • 增大客户端的句柄数
  • 使用连接池并且在读取服务端响应数据时加上超时时间

显然,第一个解决方式治标不治本,改大句柄数,当请求量变大的时候,仍然会出现句柄泄漏的情况

第二种方式相对靠谱很多

  • 首先,咱们将发送 udp 包给服务端后,等待读取服务端的回包时,设置超时时间,超时后读取失败,释放或者归还句柄
  • 维护一个内部的连接池,减少每一次创建句柄消耗的资源和时间,使用的时候从池子里面获取句柄,使用完毕之后再归还句柄

自定义连接池的编写 customer_pool

那么对于连接池,我们实际上是可以自己来进行造轮子的,仅用于学习,实际使用的话,自然还是会去使用经过大众考研过的公共开源库,我们可以来基本的分析和研究一下一个连接池需要有些什么?

  • 创建池子,关闭池子,池子的关闭状态
  • 从池子中获取连接,归还连接,销毁当前连接
  • 池子中能容纳的最大连接数,最小连接数,当前连接数
  • 根据当前实际的连接数来对池子进行扩容和缩容
  • 池子中创建连接的函数具体实现

当然,我们自己来体会一下连接池以及演示上述 udp 的 demo,我们仅实现如下几个简单功能作为演示

  • 创建池子,池子的关闭状态
  • 从池子中获取连接,归还连接
  • 池子中能容纳的最大连接数,最小连接数,当前连接数
  • 池子中创建连接的函数具体实现

对于池子中具体链接的销毁,池子的关闭,池子的扩缩容,以及其他高级使用,xdm 可以进行扩展

customer_pool demo

自定义连接池,实际上咱们是使用 chan 通道来进行实现,具体源码可以查看:https://github.com/qingconglaixueit/customer_pool/blob/master/customer_pool/pool.go

  1. 定义连接池 MyConnPool 数据结构,和创建连接池

    • MyConnPool 结构中的 sync.Mutex 主要是用于控制多协程中 非 pool 成员的其他成员的互斥,我们知道 chan 内部是有锁进行控制的

image.png

image.png

  1. 获取对象的具体实现

  • 从池子中获取对象,如果获取不到则默认查看当前的池子状态是否可以创建新的连接
  • 若可以,则直接创建连接,返回对象
  • 此处在进行池子成员的变动时,需要加锁进行控制
func (conn *MyConnPool) GetObject() (interface{}, error) {return conn.getObject()
}
func (conn *MyConnPool) getObject() (interface{}, error) {if conn.isClosed {return nil, errors.New("pool is closed")}// 从通道里面读,如果通道里面没有则新建一个select {case object := <-conn.pool:return object, nildefault:}// 校验当前的连接数是否大于最大连接数,若是,则还是需要从 pool 中取// 此时使用 mutex 主要是为了锁 MyConnPool 的非通道的其他成员conn.Lock()if conn.currentConn >= conn.maxConn {object := <-conn.poolconn.Unlock()return object, nil}// 逻辑走到此处需要新建对象放到 pool 中object, err := conn.connFun()if err != nil {conn.Unlock()return nil, fmt.Errorf("create conn error : %+v", err)}// 当前 pool 已有连接数+1conn.currentConn++conn.Unlock()return object, nil
}
  1. 释放对象的具体实现

  • 使用完毕对象之后,需要归还
  • 具体归还操作,则是将具体的连接再丢回通道里面即可
func (conn *MyConnPool) ReturnObject(object interface{}) error {return conn.returnObject(object)
}
func (conn *MyConnPool) returnObject(object interface{}) error {if conn.isClosed {return errors.New("pool is closed")}conn.pool <- objectreturn nil
}
  1. 具体的应用

简单写一个 udp 服务端

  • 可以查看源码地址:https://github.com/qingconglaixueit/use_common_pool/blob/master/server/main.go
  • 代码注释部分用于测试超时的效果

使用咱们上述的自定义连接池编写客户端的 demo

具体源码地址:https://github.com/qingconglaixueit/customer_pool/blob/master/main.go

  1. 定义咱们有 udp 连接的对象
  • 定义 PoolTest 对象,并简单的将 udp 连接加入到成员中
  • 编写创建 udp 连接的函数 connectUdp
  • 初始化连接池,设置池子最大 3 个连接,最小 1 个连接,实际创建连接函数为 connectUdp()
type PoolTest struct {Conn *net.UDPConn
}var myPool *customer_pool.MyConnPoolfunc init() {myPool = customer_pool.NewMyConnPool(3, 1, func() (interface{}, error) {return connectUdp()})if myPool == nil {log.Panicln("NewMyConnPool error")return}log.Println("myPool == ", myPool)
}
// 创建连接函数
func connectUdp() (*PoolTest, error) {// 创建一个 udp 句柄log.Println(">>>>> 创建一个 udp 句柄 ... ")// 连接服务器conn, err := net.DialUDP("udp", nil, &net.UDPAddr{IP:   net.IPv4(127, 0, 0, 1),Port: 9998,})if err != nil {log.Println("Connect to udp server failed,err:", err)return nil, err}log.Printf("<<<<<< new udp connect %+v", conn)return &PoolTest{Conn: conn}, nil
}
  1. 获取到连接对象之后,咱们给 udp server 写入数据
  • GetObject() 获取具体的对象,获取到连接
  • SendMsg 进行具体消息的发送
  • ReturnObject() 将具体的对象归还到池子中
  • 其中代码被注释掉的部分,是用力验证超时效果的,感兴趣的 xdm 可以将代码打开尝试一波

image.png

  1. 效果展示

最后补充上咱们的 main 函数,就可以进行测试验证了

func main() {for i := 0; i < 10; i++ {msg := fmt.Sprintf("send udp data is %d", i)go SendMsg(msg)}time.Sleep(2 * time.Second)
}

启动咱们的 udp 客户端,和 udp 服务端,我们可以查看到如下效果

客户端效果:

同时启了 10 个协程,每一个协程都会去池子里面拿连接对象,如果池子有现成的则直接使用,如果没有现成的,那么就新建一个连接, 如果当前池子已创建连接已经等于最大值,那么只能等着池子中有连接归还的时候再进行分配

  • 总的来说,当前 demo 只会创建 3 个 udp 连接句柄

服务端效果:

可以看到服务端收到的 10 个请求,实际上只有 3 个句柄在多次请求

再一次印证了客户端实际上确实只创建了 3 次 udp 句柄

上述是自定义简单连接池的基本 demo,关于 udp 超时处理的内容就不做演示,感兴趣的 xdm 可以下载源码来进行查看效果

https://github.com/qingconglaixueit/customer_pool

使用 go-commons-pool

当然,我们大致知道连接池基本是都有哪些组成部分,可以如何玩之后,我们来应用一个 golang 通用的连接池 go-commons-pool, 源码地址为:https://github.com/jolestar/go-commons-pool

use_common_pool demo

应用 go-commons-pool 咱们的 demo 仅验证该库的通用和便捷,对于上述我们自定义的池子,咱们使用到的 udp 涉及到的代码,可以基本不用变动,直接使用 go-commons-pool 直接网上套即可

和咱们自定义池子不一样的地方

  • init 初始化池子的方法和配置不一样
  • SendMsg 方法,实现时使用的池子句柄不一样
  • 当然,go-commons-pool 会好太多

实际 demo 为:

  • 其余截图上未体现的 connectUdp(),(this *PoolTest) SendMsg(data []byte) , 和上述自定义池子实现方式完全一致

此处初始化池子配置,咱们也是一样传入具体池子最大的对象数,使用池子的默认配置,传入咱们创建连接的具体函数 connectUdp()

对于到 main 函数 和 SendMsg 函数,咱们的用法和写法基本完全一致

自然,效果也是一样的

当然对于 go-commons-pool 池子还有其他很多有意思的东西,感兴趣的可以来一起阅读以下他的源码,如下为当前池子的基本数据结构和创建池子的代码,咱们可以根据这个结构来追以下代码

代码目录如下:

./pool.go

  • 基本数据结构
  • 创建池子代码

image.png

至此,本文结束

文中涉及到的源码地址:

  • customer_pool https://github.com/qingconglaixueit/customer_pool
  • use_common_pool https://github.com/qingconglaixueit/use_common_pool
  • go-commons-pool https://github.com/jolestar/go-commons-pool

感谢阅读,欢迎交流,点个赞,关注一波 再走吧

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~
可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI

相关文章:

线上 udp 客户端请求服务端客户端句柄泄漏问题

本题分别从如下三个方面来分享&#xff1a; 问题描述 自定义连接池的编写 common_pool 的使用 问题描述 线上有一个业务&#xff0c;某个通服务通知 udp 客户端通过向 udp 服务端&#xff08;某个硬件设备&#xff09;发送 udp 包来进行用户上线操作 当同时有大量的请求打到…...

合宙Air724UG LuatOS-Air LVGL API控件-窗口 (Window)

窗口 (Window) 分 享导出pdf 示例代码 win lvgl.win_create(lvgl.scr_act(), nil) lvgl.win_set_title(win, "Window title") -- close_btn lvgl.win_add_btn_right(win, "\xef\x80\x8d") -- --lvgl.obj_set_event_cb(cl…...

80 # 图片防盗链

referer 来源&#xff0c;表示这个资源被谁引用过&#xff0c;可以用来做防盗链。 我们新建文件 no-referer.js const fs require("fs"); const path require("path"); const url require("url"); const http require("http");h…...

App自动化测试持续集成效率提高50%

持续集成是一种开发实践&#xff0c;它倡导团队成员需要频繁的集成他们的工作&#xff0c;每次集成都通过自动化构建&#xff08;包括编译、构建、自动化测试&#xff09;来验证&#xff0c;从而尽快地发现集成中的错误。让正在开发的软件始终处于可工作状态&#xff0c;让产品…...

LeetCode —— 复写零(双指针)

题目链接 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题目解析 将数组中出现的每个零复写一遍&#xff0c;然后将其他元素向右平移&#xff0c;数组长度不能改变。 法一&#xff1a;使用额外空间的做法 class Solution { public:void duplica…...

【Vue篇】Vue 项目下载、介绍(详细版)

如何创建一个vue项目&#xff1f;首先要有环境&#xff0c;如下&#xff1a; nodejs vue-cli如果有以上的工具就直接跳过安装教程 【Vue篇】mac上Vue 开发环境搭建、运行Vue项目&#xff08;保姆级&#xff09; 创建vue项目 选择一个位置&#xff0c;你要存放项目的路径&…...

Python批处理(一)提取txt中数据存入excel

Python批处理&#xff08;一&#xff09;提取txt中数据存入excel 问题描述 现从冠层分析软件中保存了叶面积指数分析的结果&#xff0c;然而软件保存格式为txt&#xff0c;且在不同的文件夹中&#xff0c;每个文件夹的txt文件数量不固定&#xff0c;但是txt文件格式固定。现需…...

只考一门数据结构!安徽工程大学计算机考研

安徽工程大学 考研难度&#xff08;☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文992字&#xff0c;预计阅读&#xff1a;3分钟 2023考情概况 安徽工程大…...

Ubuntu 20.04出现蓝牙无法打开的问题(已解决)

安装Ubuntu20.04后&#xff0c;蓝牙无法打开&#xff0c;按钮开启后蓝牙仍处于关闭状态 解决方法&#xff08;四种方式&#xff09; 1.卸载并重新加载btusb内核模块&#xff08;支持蓝牙设备的内核模块&#xff09; sudo rmmod btusb sleep 1 sudo modprobe btusb2、安装蓝牙工…...

并发测试工具 apache-jmeter使用发送post请求JSON数据

目录 1 下载安装 2 汉化 3 创建高并发测试 配置线程组 创建web请求 创建监听器 结果树 汇总报告 为web请求添加token 添加Content-Type用于发送json 4 启动测试 5 查看结果 1 下载安装 官网Apache JMeter - Download Apache JMeter 解压运行 2 2 汉化 打开软件…...

牛客练习赛115 A Mountain sequence

题目&#xff1a; 样例&#xff1a; 输入 3 5 1 2 3 4 5 3 3 3 3 3 1 2 1 输出 16 1 3 思路&#xff1a; 依据题意&#xff0c;再看数据范围&#xff0c;可以知道暴力肯定是不可能了&#xff0c;然后通过题目意思&#xff0c;我们可以排列模拟一下&#xff0c;这里排列所得结…...

通过git bash激活虚拟环境遇到的问题

直接git bash后用conda activate激活一直报错 报错如下&#xff1a; CommandNotFoundError: Your shell has not been properly configured to use ‘conda activate’. If using ‘conda activate’ from a batch script, change your invocation to ‘CALL conda.bat activa…...

EasyAVFilter代码示例之将摄像机RTSP流转成RTMP推流输出

以下是一套完整的RTSP流转RTMP推流功能的开发源码&#xff0c;就简简单单几行代码&#xff0c;就可以完成原来ffmpeg很复杂的调用流程&#xff0c;而且还可以集成在自己的应用程序中调用&#xff0c;不需要再单独一个ffmpeg的进程来调用&#xff0c;方法很简单&#xff1a; #i…...

【【C语言康复训练-4】】

C语言康复训练-4 head.h #pragma once #define ROWS 11 #define COLS 11 #define ROW 9//为什么会在头文件中定义两个 因为1到9是我们想要实现的标准单元 #define COL 9 //但是对于我们幕后调控者&#xff0c;对边角上并不能和其他一样方便操作&#xff0c;所以我们向外拓展了…...

[DM8] DM-DM DBLINK DPI方式

前言 对于DM与DM之间的DBLINK&#xff0c;三种方式中&#xff0c;使用DPI方式配置上最为方便&#xff0c;ODBC方式需要安装ODBC包并配置ODBC数据源&#xff0c;dmmal方式需要设置MAL_INI数据库参数、配置dmmal.ini文件并需要重启数据库服务。 dpi类型的dblink&#xff0c;达梦…...

创建了一个名为nums_list的vector容器,其中存储了一系列的pair<int, int>

vector<pair<int, int>> nums_list;for (int i 0; i < nums.size(); i) {nums_list.emplace_back(i, nums[i]);}这段代码创建了一个名为nums_list的vector容器&#xff0c;其中存储了一系列的pair<int, int>。代码的逻辑如下&#xff1a;1. 创建一个空的…...

SpringMVC文件上传、文件下载多文件上传及jrebel的使用与配置

一.文件上传 1.导入依赖 <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version> </dependency> 2.配置文件上传解析器 在spring-mvc.xml文件中添加文件…...

Leetcode143. 重排链表

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln - 1 → Ln请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能只…...

Git 回顾小结

Git是一个免费开源&#xff0c;分布式的代码版本控制系统&#xff0c;版主开发团队维护代码 作用&#xff1a;记录代码内容&#xff0c;切换代码版本&#xff0c;多人开发时高校合并代码内容 Git常用命令 命令作用注意git -v查看Git版本git init初始化本地Git仓库git add 文件…...

响应式布局(3种) + flex计算

响应式布局 1.媒体查询2.使用百分比、rem、vw、vh等相对单位来设置元素的宽度、高度、字体大小等1.rem与em2.vw、vh、vmax、vmin 3.Flexboxflexbox计算题 响应式布局是指同一个页面在不同屏幕尺寸下有不同的布局。 1.媒体查询 媒体查询是最基础的实现响应式的方式 使用media关键…...

Pytorch从零开始实战01

Pytorch从零开始实战——MNIST手写数字识别 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——MNIST手写数字识别环境准备数据集模型选择模型训练可视化展示 环境准备 本系列基于Jupyter notebook&#xff0c;使用Python3.7.12&#xff0c;Py…...

inappropriate address 127.0.0.1 for the fudge command, line ignored 时间同步的时候报错

1、安装ntp服务后&#xff0c;启动ntpd正常&#xff0c;但是在查看ntpd服务状态时&#xff0c;有一个红色的报错&#xff0c;报错信息如下&#xff1a; inappropriate address 127.0.0.1 for the fudge command, line ignored 2、解决方法&#xff1a;编辑ntp配置文件&#xf…...

linux并发服务器 —— 项目实战(九)

阻塞/非阻塞、同步/异步 数据就绪 - 根据系统IO操作的就绪状态 阻塞 - 调用IO方法的线程进入阻塞状态&#xff08;挂起&#xff09; 非阻塞 - 不会改变线程的状态&#xff0c;通过返回值判断 数据读写 - 根据应用程序和内核的交互方式 同步 - 数据的读写需要应用层去读写 …...

生信教程|替代模型选择

摘要 由于教程时间比较久远&#xff0c;因此不建议实操&#xff0c;仅阅读以了解学习。 在运行基于可能性的系统发育分析之前&#xff0c;用户需要决定模型中应包含哪些自由参数&#xff1a;是否应该为所有替换假设单一速率&#xff08;如序列进化的 Jukes-Cantor 模型&#xf…...

redis持久化、主从和哨兵架构

一、redis持久化 1、RDB快照&#xff08;snapshot&#xff09; redis配置RDB存储模式&#xff0c;修改redis.conf文件如下配置&#xff1a; # 在300s内有100个或者以上的key被修改就会把redis中的数据持久化到dump.rdb文件中 # save 300 100# 配置数据存放目录&#xff08;现…...

Python 连接 Oracle 详解

文章目录 1 首先&#xff0c;安装第三方库 cx_Oracle2 其次&#xff0c;配置命令 1 首先&#xff0c;安装第三方库 cx_Oracle 参考 CSDN 博客&#xff1a;Python 安装第三方库详解&#xff08;含离线&#xff09; 2 其次&#xff0c;配置命令 import cx_Oracle# 1.数据库连接…...

认识模块化

1. 模块化的基本概念 1.1 什么是模块化 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说&#xff0c;模块是可组 合、分解和更换的单元。 1. 现实生活中的模块化 2.编程领域中的模块化 编程领域中的模块化&#xff0c;…...

2023年及以后语言、视觉和生成模型的发展和展望

一、简述 在过去的十年里,研究人员都在追求类似的愿景——帮助人们更好地了解周围的世界,并帮助人们更好地了解周围的世界。把事情做完。我们希望建造功能更强大的机器,与人们合作完成各种各样的任务。各种任务。复杂的信息搜寻任务。创造性任务,例如创作音乐、绘制新图片或…...

OpenLdap +PhpLdapAdmin + Grafana docker-compose部署安装

目录 一、OpenLdap介绍 二、PhpLdapAdmin介绍 三、使用docker-compose进行安装 1. docker-compose.yml 2. grafana配置文件 3. provisioning 四、安装openldap、phpldapadmin、grafana 五、配置OpenLDAP 1. 登陆PhpLdapAdmin web管理 2. 需要注意的细节 内容介绍参考…...

Java | 排序内容大总结

不爱生姜不吃醋⭐️ 如果本文有什么错误的话欢迎在评论区中指正 与其明天开始&#xff0c;不如现在行动&#xff01; 文章目录 &#x1f334;前言&#x1f334;算法整理&#x1f334;两个结论&#x1f334;总结 &#x1f334;前言 本文内容是关于选择排序、冒泡排序、插入排序…...