小内存服务器引发的mariadb无法连接问题

由于资源限制问题,有一套PHP的系统部署在一台512M内存的服务器上。系统是centos8,采用nginx + php-fpm + mariadb的方式部署服务。因为这套系统每天也没有几个用户请求的,并且一开始也没什么问题。但是某一天,点击多几次页面之后,就出现数据库无法连接。并且无法使用systemctl去重启mariadb,然后从maraidb的日志得出内存不足的信息。

It is possible that mysqld could use up to key_buffer_size

日志出现上面的信息,既然内存不足,那么直接加内存即可。但是由于某些原因不能升级服务器,那么好办,直接加虚拟内存。似乎问题得到解决,但过不了多久,变成了请求504错误。

这个时候就应该登录服务器去分析问题,结果服务器也登录不了了,在云服务商的面板看了一下,发现读磁盘高达100m每秒。怎么会有这么高的IO呢?很简单的原因,因为配置了虚拟内存,应该是内存不断读取,结果变成了磁盘读写。只好先强制重启服务器,再去处理。

首先,不再配置虚拟内存,而是要降低一下内存的使用。所以先修改mariadb的配置,结果依旧。然后通过命令查询占用内存过多的进程列表。结果发现大量php-fpm进程,原因应该就是php-fpm了。那么直接限制php-fpm的进程数量,问题到此完美解决。

小团队多语言多框架开发的尝试

对于小团队而言,一般是技术负责人熟悉什么语言和什么框架就会使用那种语言和框架。但是如果选用的语言和框架过于小众的话,招人又是一个问题了。那么其中一个解决方案就是允许每个同学用自己熟悉的框架来开发,但是这又涉及到每个人要独立编写一个服务。但是这么多个服务怎么组合起来呢,如果服务之间都互相调用肯定是行不通的。

那么可行的办法是什么呢?一个是把公用的部分抽离出来,例如登录系统。然后每个服务都去请求登录系统来确定用户身份。但是要尽量避免服务过细,尽量减少服务间调用,因为小企业过多服务真心不好去维护。

python对接企业微信会话存档

会话存档的推出是企业微信为了让企业可以了解员工与客户的互动情况,也为了避免员工拿走公司的客户资源,现在开通可以寻找一些有资质的企业微信服务商去开通(例如语鹦企服,https://crm.bytell.cn/)。

但是企业微信现在只提供c++和java的sdk去调用接口,但是很多企业会用python,golang,php等其它语言开发应用。下面简单说一下python如何去调用企业微信会话存档接口。首先下载会话存档的sdk,然后仅需要C_sdk文件夹里面的一个so文件。

python调用该so既可以对接企业微信会话存档接口

dll = ctypes.cdll.LoadLibrary('libWeWorkFinanceSdk_C.so')

上面是加载so,然后dll对象就可以调用对应的接口,接口的定义可以参考WeWorkFinanceSdk_C.h文件。关键是python调用so的时候,要声明调用函数的参数和返回值类型

dll.NewSdk.argtypes = []
dll.NewSdk.restype = ctypes.c_void_p

上面就是定义初始化企业微信sdk函数,其中指针类型在python里面可以定义为ctypes.c_void_p,而字符数组指针可以定义为ctypes.c_char_p。而实际调用函数的时候,ctypes.c_char_p类型的参数python要传递byte[]类型的数据过去。

总的来说,其它语言开发企业微信会话存档,就是简单的调用C库即可。

python能否构建大型应用?

提到python,很多同学的第一印象是开发快运行慢,觉得做不了大项目。但其实在高并发环境下,出现瓶颈的大部分不是在开发语言,而是数据库。不相信的同学可以测试一下数据库并发写入的速度究竟能达到多少,维护过的这么多个系统,包括秒杀的系统,只要设计得当,python写的系统在单服务器(1核512m)应对过千并发都不是问题。别小看1千并发,大部分情况下,一个系统有超过十个并发都挺不错的,哪有那么多千万级并发。

下面从各个维度分析python能否构建高并发大型应用:

涉及大量CPU运算的场景,例如做分词这种场景,基本上可以换成java或者c来处理了。曾遇过一个场景,用20台1核1G服务器,全部cpu跑满。换成java重写之后,仅需一台服务器,并且cpu最多去到50%。

内存场景,一般来说没有内存泄露,内存不会有太大的波动。基本上并发上去了,内存也不会增长多少。并且相对于java这种语言,python真心节省内存。

网络IO,包括请求第三方api和数据库读写。这种场景,一方面tornado这种异步框架可以保持大量的连接,并且不阻塞后续的请求。另一方面,哪怕django,flask这种同步框架,加上gevent的补丁,同步写的代码也有异步的效果。

频繁的架构调整,因为python是弱类型语言,所以接口的变更,或者传递错误的类型都很难在开发阶段发现。所以依赖规范化的开发,和严谨的测试。

对于这个问题,我的答案是python是可以构建大型应用的。并且在高并发情况下也有对应的解决办法。