Mini Server问题集锦

Nextcloud

更新版本时错误,[version 22.2.x]

Step 4 is currently in process. Please reload this page later

解决方法:

nextcloud路径/data/updater-xxxxxxx文件夹

frp

运行时错误, [verion 0.33、0.37.1 、0.38]

2021/11/16 22:23:50 [E] [control.go:158] [dbf0bbaf2a7be98c] work connection closed before response StartWorkConn message: read tcp 192.168.199.111:59690->xx.xx.xx.x:443: read: connection reset by peer

当天流量太大,网络运营商切断了链接,过一天就好了。

分布式系统讲义(二、负载均衡策略)

同学们欢迎回来,这节课,我们来讨论分布式系统的那些事当然负载均衡的问题,什么是负载均衡的问题,呢就是上一节课。我们讲过分布式系统呢可能会有非常多的服务器来呃来组成这个系统。那么,这个系统,它是如何分工的呢?当很多用户都过来发送请求的时候,这些请求应该怎么样,去被分摊到不同的服务器上,让他们来处理呢?这个呢,实际上就是负载均衡要解决的一个问题。负载惊鸿,从字面意思就是让我们的服务器的负载,都能够均衡些。

这是字面意思。那么,我们是怎么做的呢?我们还是一个WEB网站为例子,当非常多的用户同时或者说任意同一段时间里面都来请求我们的系统的时候,我们就要把这些请求给他给分流分流到不同的服务器上。然后让他们老师让不同服务器呢,然后都能够同时来去处理这样用户。那么,这样做的一个目的是什么呢?第一个就是一定要让我们的服务器就是能够均匀地去呃去承受这些用户的请求,其实从用户的那个角度来讲呢,就是它能够及时的,它发出的请求能够被及时都给处理。

那么,我们来举这么一个例子啊,假如我们没有负载均衡的情况会怎么样?一个分布式系统,哎,哪怕强,如美国队长。那么,非常多的一个系统,它来一个请求就出了一个请求。那么,他也是处理不过来的,而好在呢我们是有非常多的一些服务器,我说一些计算单元,然后来平摊。那么,这些工作,这样的话,我们就我们就会让这个系统,呢然后在同一时间就可以处理非常多的一个系统,呃非常多的一个请求。那么,我们是怎么样去用什么一个方法,然后去把这些系统给它分流,呢这个时候,呢,就说到一个负载均衡的一些策略,最常见的一种两种策略呢是一个时装的,另外一个是软的意思,呢绒的的意思,呢实际上是轮询的意思就是来一个请求分配给你当前的第一台服务器。

那么,来第二个请求的时候,然后就把这一个请求呢,分配给第二个处理器进行呃进行处理,第三个就返回第三个,然后所有的服务器转了一圈以后,然后就这么轮询的完成。那么随机这种策略呢然后也是很好理解了。当一个请求过来的时候,它会随机的a选一台服务器,给他去分配处理这么一个星球。这样这两种复赛翻飞的策略,呢然后都能够让所有的机器呢然后都在运行,而不会出不会出现某一台机器,比如说不干活,另外一些机器又特别忙是吧?

这样子,呢然后就可以更快地去处理一些用户用户理解请求呃这么做的一个目的,呢实际上就是为了让那个用户呢然后及时的去那个得到呃得到处理。其实我们有的时候,我们可能会去一些。比如说政府部门或者说去银行办业务的时候,其实我们会排队,其实,这个原理呢,其实已经是非常类似了,在银行当中获得政府过程当中,它有非常多的一扇窗口。那么,他的那个排队系统用的是什么样的策略?呢其实很多时候是一个荣的是吧?那其实也不全是中的落地呃也不全是一个软得对,因为实际过程中很复杂,其实,我们解决计算机的问题。

啊跟我们的解决。现实生活中这么一个I期银行排队这么一个我其实很类似的,但是呢,我们也面临一个一个问题,就是有的服务器呢,年富力状有的服务器呢,性能比较差。那么这个时候你就不能用,就简单粗暴地用轮询,或者说说用随机的这种方法变得给他去哪个范围这个任务。那么,这个时候,有用的一个什么方法呢?就是一个加权,我们叫价钱的一个轮询,有些有些服务器呢年富力强,我们给他给他个全职,比如说一点吧,有些机器呢弱一点,啊我们给它的系数是0.8。
这样子的话,那么,一点的服务器他就可以接受更多的那些处理接触更多的请求去处理它,能够更快的呢,然后去返回那个性情用户请求的结果就有这么一种方法。那么,我们除此之外呢,实际上还有一种负载均衡方法。教你的意思呢,是叫最小负载的一种方法,呃这句话是怎么理解呢?这句话呢?实际上是一种比较,我们设置权重都要学人工的去标,实是把这台机器是个年富力强的还是一个呃,比如说是一个特别就的这么一个电脑,一个信号。那么,我们能不能自动系这个时候呢,实际上在我们的负载均衡里面,我们会写一个算法,我们会依据。
比如说CPU某一台机器的响应时间,或者说某台机器,它的那个队列的一个等待时间,我们通过一个一个算法,然后我们就能计算出它的全职来获得全职高的,呢它依然会给他分配更多的更多的一些请求我举个例子,大家如果是做c加加开发的话,会有一个b r PC的c加加框架,它里面那就有一个叫LA的这么一个负载均衡的一个算法,它呢,就依据它下游的服务器的一些等待时间,比如说CPU的负载还有那个返回的状态么?和响应时间,他就能判断出这台机器是不是一个性能更高的机器还是一个性能差的机器?

这样子的话,他就可以比较自动的去那个吧,就是自动的,去给那个依据机器的不同性能给他分配不同数量的一些请求。嗯,咱们再说一下。那么负载均衡他,有的时候,它是依据什么呢?我们依据什么来判断,就说我给哪台机器呢?其实还有一种方式就是我,如果我们做,如果我们做一个映射和随机的话,我还可以通过。比如说听说我校4层4层负载均衡还有呢?叫7层负载均衡这句话是什么意思呢?7层和4层负载均衡脑,只要指的是TCP IP当中的第7层和第4层4层呢,是指我们依据IC IP的地址呢,然后呢,我们就给他进行随机的去分配。

呃依据这个IP地址,然后给他做负载均衡,然后给他分配的后面相应的机器当中去。还有一个7层负载均衡,呢实际上是一具,比如说第7层实际上在TC标题里边是应用层,那么我们就一句在应用层当中的一些什么一些带过来的一些信息,我说是一些cookie,就类似于这样的一些应用带过来一些信息呢,然后给他趣,唉,比如说随机分配给那个下游的一些服务器,这个呢,是依据网络环境,然后我们来去见4层呢还是西,曾因为4层大家都知道的IP内层会更基础一些,会底层一些好了,大家我们来就是总结和分享一下。

总结一下,就是我们的负载均衡的方法都有哪些几种呢?实际上其实呢?都有这四种,主要都是有4楼,第一个呢,就是轮询随机。还有最小负载对外还有一个最小链接,但是也让过程中我们可能不是在实际过程中不会经常常见,我们来那个给负载均衡下一个定义啊。那么,食什么是负载均衡负载均衡,其实它的本质,啊它是一个起到一个路由的作用就是当一个用户过来的一个用户的请求。过来的时候,我们怎么给他录入到后端的一台机器上,让他去处理。
这有这个嗯完成了这么一个负载均衡以后,呢实际上分布式对于一个应用来讲,是否就结束了呢?呃其实不是的,啊就是我们怎么样去找到它下面的服务。呢这个内容呢我们会在下节课的时候,然后进行一个呃进行一个讲解。

分布式系统讲义(一、什么是分布式系统?)

同学们大家好,今天由我来同大家一起,通过大白话的方式,聊一聊分布式系统的那些事儿。

到今天为止,分布式系统已经是一种非常基础或者说非常通用的一种技术了。在互联网应用的后端服务中,分布式技术几乎无所不在,那么到底什么是分布式系统?我们为什么要用分布式系统?它到底有哪些优势?以及我们今后工作中面临的一些问题,如何通过设计分布式系统,解决这些问题呢。围绕着这些问题,我们在这门课中展开来讨论。

回到这门课的最开始的一个问题,什么是分布式系统?在给出这个定义之前,我们先来看一下一个后端服务的演化过程,拿一个外部网站来举例,最早的时候,它只部署在一台机器上,这一台机器承受的用户的数量是很有限的,一台服务器大概只能承受住300个人同时进行访问,但是用户量会慢慢的变大,从最开始的300到后来的1000人,在到后来的几万人。中国现在大概有接近10个亿的网民,这么1个数量级的用户数,我们这么一台服务器绝对是承受不住的,这个时候应该怎么办?

一般想到的它有两种方法,我们说的第一种方法升级我们的服务器,把我们的服务器从一个性能比较差的变成一个性能比较好的,它数据的存储本来是比如说只有几百g然后把它变成几个t这么一个容量的磁盘放到这个服务器里边去,这样子也能解决问题,但是它只解决了比如说用户数从300到1000这么一个问题,但是我们的用户数如果是几个亿,那个时候怎么办?

我们会有一个第二种方法,就是用几千台机器,然后让几千台机器,然后相互协作,去满足几亿用户的这么一个数量的这么一个访问,所以这个方法基本上已经给出了一个分布式系统的一个雏形了,由此我们其实是可以引出来,那么分布式系统到底是一个什么样的定义。然后出自分布式的概念与设计这么一本书,就是国外的一个经典的用来用来介绍分布式的这么一本经典巨著。

他说分布式系统是指位于联网计算机上的组件,仅通过传递信心进行通信和协调行动的系统。同时他又给了这么一句话叫分布式系统,它是一个即便是已经崩溃了部分机器,但是它仍然能够完成工作这么一个系统。除此听到这么几个定义,大家可能还是感觉比较细。

我来给大家举一个例子,我所在的智能平台部,我所负责的系统就是一个服分布式系统效果广告的预估服务,那么这个预估服务现在有多少台机器,这个事情我给大家说一下,大概是就是说大概是有3000台左右的机器,那么我们的小广告服务大概有3000台机器这么一个数量级的,而且这3000台机器各有分工,相互协作,然后能够满足我们现在广告这么一个业务。

同时它也满足这么一个定义。如果只有一部分机器宕机,那么它仍然能够满足效果广告,预估的工作,而不至于整个服务都不可用。

今天的例子,介绍什么是分布式系统,我们就是到此为止,下节课我们会去探索分布式系统它面临哪些技术挑战。谢谢大家。

Linux一些查看系统状态的命令

查看网卡速率

ethtool eth0 |grep Speed

这里的Speed是网卡的实际最大速率;如果开启了自动协商,就是是网卡和交换机协商之后的速率。

附带一个自动化脚本

PREFIX="p1p1"
ETH=ifconfig |grep ${PREFIX} | head -n1 | awk -F":" '{print $1;}'

if [ -z "${ETH}" ];then
   echo "emxx is not found"
   ifconfig
   exit 1
fi

ethtool eth0 |grep Speed

查看内存信息

  • 支持的内存槽数
  • 支持的最大内存

sudo dmidecode -t memory

输出如下:

# dmidecode 3.2
Getting SMBIOS data from sysfs.
SMBIOS 2.8 present.

Handle 0x0028, DMI type 16, 23 bytes
Physical Memory Array
        Location: System Board Or Motherboard
        Use: System Memory
        Error Correction Type: None
        Maximum Capacity: 8 GB
        Error Information Handle: Not Provided
        Number Of Devices: 2

Handle 0x002A, DMI type 17, 40 bytes
Memory Device
        Array Handle: 0x0028
        Error Information Handle: Not Provided
        Total Width: 64 bits
        Data Width: 64 bits
        Size: 4 GB
        Form Factor: DIMM
        Set: None
        Locator: A1_DIMM0
        Bank Locator: A1_BANK0
        Type: DDR3
        Type Detail: Unknown
        Speed: 1600 MT/s
        Manufacturer: Samsung
        Serial Number: 37A52995
        Asset Tag: A1_AssetTagNum0
        Part Number: M471B5173DB0-YK0
        Rank: 1
        Configured Memory Speed: 1333 MT/s
        Minimum Voltage: 1.35 V
        Maximum Voltage: 1.5 V
        Configured Voltage: 1.35 V

Handle 0x002C, DMI type 17, 40 bytes
Memory Device
        Array Handle: 0x0028
        Error Information Handle: Not Provided
        Total Width: Unknown
        Data Width: 64 bits
        Size: No Module Installed
        Form Factor: DIMM
        Set: None
        Locator: A1_DIMM1
        Bank Locator: A1_BANK1
        Type: Unknown
        Type Detail: Unknown
        Speed: Unknown
        Manufacturer: A1_Manufacturer1
        Serial Number: A1_SerNum1
        Asset Tag: A1_AssetTagNum1
        Part Number: Array1_PartNumber1
        Rank: Unknown
        Configured Memory Speed: Unknown
        Minimum Voltage: Unknown
        Maximum Voltage: Unknown
        Configured Voltage: Unknown

服务迁移至Kubernetes实践总结

梗概

Kubernetes相比传统的集群管理方式,表现出更多优势,因而国内互联网公司也都已经大规模使用 Kubernetes。

Kubernetes 拥有大量的用户群体和落地实践,做为生产环境的编排系统在成熟度和稳定性上已得到业界的认可。对于开发工程师来讲,把服务部署到k8s中,将会是运维工作的常态。

把服务迁移到K8S集群之前,需要对服务本身进行一些升级,对K8S进行适配。本文对升级过程中的一些常见问题,以及注意事项进行总结。

把服务迁移到K8S的意义是什么?

先说K8S有哪些特性呢?依据官方文档,有自我修复、弹性伸缩、自动部署和回滚、服务发现和负载均衡、机密和配置管理、批处理等特性。

这些特性无疑解放了开发工程师运维服务器集群的人力,可以把节省出的精力投入到系统设计、编码开发等价值更高的工作当中。

不要只看收益,不看风险。

K8S带给我们诸多收益的同时,也要注意到K8S给我们带来新的问题。

容器漂移

容器漂移是最常见的问题。容器在一台机器关闭,然后再另外一台机器上被启动。发生容器漂移的原因有滚动发布、物理机故障被回收、手工关闭容器、K8S集群进行碎片整理等。

容器漂移会给系统带来的负面影响有,节点一段时间内不可用、IP地址变化、缓存丢失、临时数据文件丢失等。

资源碎片

总有机器的一部分小块资源被闲置,却又不能满足有大块资源需求的服务。资源碎片会影响K8S集群的机器利用率,严重时会影响服务的发布。

资源隔离不完善-IO不能隔离

目前容器技术,没有实现对磁盘IO的资源隔离,因此同一宿主机上如果存在两个磁盘IO密集型的服务,有很大概率会相互影响。

尽管当前的容器技术已经实现对网络IO资源的隔离,但是可能受限于K8S的版本,以及公司内部CICD系统不提供对网络IO隔离的设置,因此对于网路IO资源密集的服务,部署到K8S时也要谨慎处理。

不能隔离的 IO 类型有:

  • 内存带宽
  • 网络带宽
  • 文件带宽

root权限

一些服务会调用只能root才有权限访问的接口,比如mlock。这些服务如果迁移到K8S,需要重新进行设计,因为公司里的CICD服务往往不会允许k8s中的容器以root用户运行。

系统调用失效

物理机和容器里面的接口发生了很大变化,举例说明:

  • CPU核数,获取物理机器核数的接口要替换成获取容器CPU核数的接口
  • 可用内存大小,获取物理机器内存大小的接口要替换成获取容器内存大小的接口

集群机器性能差异

k8s集群中,服务器可能来自不同厂商,采购的新旧型号不同,配件性能也可能会有差异。尤其不同cpu型号的性能差别巨大。而K8S不能把这种性能差异对应用变得透明。

一般方法是:

  • 添加机型约束
  • 把资源量化,比如1core 等于100算力(K8S暂未实现此功能)。

把服务迁移到K8S之前需要做哪一些升级?

支持容器化运行和部署

K8S本身就是容器的编排系统,所以服务要能在容器中运行起来。需要编写Dockerfile或docker-compose.yaml文件来实现编译镜像。

服务本身要具有良好的可伸缩性

服务本身需要具有容错机制,其上游也要有失败访问后的重试。除此之外,服务检测、坏点摘除、服务发现,也是必不可少的,所以需要把服务接入名字服务。

支持日志的集中采集

不同于传统的运维方法,我们难以进入每一个容器来查看进程的运行状况。把服务要接入日志中心的系统,在日志中心查阅、追踪系统状态是最好的选择。

监控指标集中上报

和把日志上报到日志中心的原因相同,把服务的监控指标,上传到监控平台/系统。而且为了减少依赖,尽可能使用SDK通过网络的方式上传监控指标,避免通过采集容器内日志文件的方式上报。

数据分片

对于一些数据分片的服务,需要有一个统一的分片管理模块。

可用性

K8S集群不总是可用的,我们在设计服务时,就要考虑对服务进行同城双活、异地多活等方式的部署。为了保证服务的可用性,把服务部署到同城不同K8S集群或者异地不同的k8s集群当中。

其他的注意事项

服务的日志自动清理,不然宿主机的磁盘会被用满,引发故障。

使用分布式文件系统来共享文件,比如ceph、OSS等。

程序异常时产生的coredump文件保留下来,以便排查问题。

自动弹性扩缩容

这是k8s的一个能大大节省运维工作,以及提升资源利用率的功能。

但自动弹性扩容在某些场景下会影响服务的可用性。以故障的灾后恢复为例,有问题的服务,被上线后,CPU负载降低,被自动缩容;问题修复后,开始重新扩容,扩容服务的时间可能是漫长的(可能加载内存数据慢、可能机器较多),服务不可用的时间也会变长。

总结

K8S也是一把双刃剑,一方面把开发工程师从繁琐的运维工作中解放出来;另一方面如何运维部署在K8S上面的服务,K8S较传统方法有较大的不同,开发工程师面对K8S这个新工具,要不断学习和总结。

算法工程团队的测试方法总结

服务于算法的工程团队的测试需求

测试的目的是为了保证在线服务的可用性、稳定性、正确性、找到并能消除系统的性能瓶颈。

后端服务的测试一般包含下面几个方面:

  • 功能测试
  • 性能测试(压力测试,测试cpu、内存、io)
  • 稳定性测试

除此之外,服务于算法的工程团队有一种特有的测试需求,就是一致性测试,包含如下两项:

  • 特征一致性验证,为了保证在线服务要保证所使用的特征传入
  • 模型一致性验证,保证在线服务和离线训练的服务一致
  • 打分一致性验证,在线模型打分与离线打分进行对比,主要为了保证在线模型的准确性

当前团队的开发特点

  • 使用C++语言开发在线服务,少数服务由python编写
  • 网络框架和协议使用 grpc/brpc/tars+protobuf
  • 微服务化,没有测试工程师,由研发工程师自主把控软件质量
  • 算法工程师和架构工程师,彼此分工协作,架构工程师需要向算法工程师提供简单便捷的测试工具。

因为上面前两点原因,当前团队无法使用当前业界里优秀的开源测试工具或平台,比如JMeter、iago 、Gatling、Grinder、Locust,还有阿里云的性能测试PTS等。因为这些工具或平台仅适用于http协议,无法满足当前团队使用的网络框架和rpc协议。

那行业中有没有其他公司做过类似的工具呢?有的公司在这方面进行了尝试,比如美团技术团队自有一套针对thrift的压测工具,可惜并不开源,参考https://tech.meituan.com/2016/01/08/loading-test.html。

最终团队只能自己开发测试工具。

团队测试开发的几个发展阶段

团队在从0到1开发在线服务过程中的同时,也在搭建团队自己的开发测试工具。工具不停地被完善,其中过程包含了下面3个阶段。

  • 测试脚本、小工具
  • 工具升级,做出流量回放工具、面向模型服务的专用测试工具等
  • 通用的后端压力测试平台

测试脚本、小工具

团队初期是通过编写测试脚本,来构造测试用例。用随机数生成的方式或通过简单的参数样本集合构造请求。

压力测试则是通过编写小工具来进行模拟上游服务的大量请求。

脚本和工具虽然简陋,但满足了项目初期的测试需求。这种测试方法持续了比较长的时间,逐渐发现如下问题:

  • 随机数生成的参数与实际情况差异较大;
  • 随着业务复杂度的提高,请求参数越来越多,参数的组合越来越多,测试脚本变多,无法管理。
  • 自动化程度低,效率不高

流量回放工具

通过拷贝线上少部分流量,落地到文件,在有测试需求时,把文件中的请求发送给待测试的服务。

这种方式存在如下问题:

  • 自动化程度依然较低,效率不高,尤其测试样本的管理
  • 录制的流量容易过时。模型和策略使用的特征,往往具有时效性。流量回放,特征已经产生变化。

专用测试工具

除了流量回放工具,团队也开发了专用的测试工具,比如面向运载算法模型的在线服务。

运载算法模型的在线服务是算法工程团队运维最多的服务,占用服务器达几千台,加载近百个版本的模型。模型频繁的迭代,需要最频繁的测试。

测试最多的方面为

  • 特征一致性验证
  • 模型的一致性验证
  • 打分的一致性验证

这里测试一致性的工具有

  • 在线diff工具
  • 特征一致性验证工具

在线diff工具

原理是,搭建线上和测试两套环境,同时发送相同流量,验证两个环境返回的字段、打分的不同。对于打分,会统计出不同精度下的差异率。差异结果,会通过监控系统的曲线展示出来。

特征一致性验证工具

原理为,保留每次请求的特征快照。对测试环境发起线上旁路流量,测试环境也同时落下特征快照,对两处快照做join之后,对比快照的不同。

专用工具实现了白屏化、可视化,但缺少通用性。不能适用于其他模块,也难以推广给其他团队使用。

通用的压力测试平台

为了解决自动化、可视化、平台化的问题,通用的压力测试工具被提出。

依据行业内积累的经验指导,尽管专用测试工具总会比通用测试工具在便捷性和功能性上要好于通用性工具。但为了节省重复在测试工具上的开发,最大可能赋能其他团队,通用的测试工具还是有一定意义。

比较容易实现的是压力测试工具。

如何设计一套通用的压力测试工具呢?

整体流程

通用的压力测试工具的基本流程,即流量的录制和回放。

但除了基本的流量回放,需要满足下面几点。

自动化、白屏化

包含两方面:

  • 流程管理的自动化
  • 流量样本的存储自动化
  • 进程管理自动化

前端管理页面由html+css+js实现;流程、存储、进程的管理的实现由脚本语言,比如python来完成;进程的所需的资源交由K8S调度和管理。

可视化

压测结果通过图表展现,常见的指标有:

  • 最大响应时间、平均响应时间
  • PV、QPS
  • TP50、TP90、TP99
  • 成功数、失败数、成功率

一般由时序数据库和图表展示工具实现,时序数据库可以选择使用Prometheus/indexdb等,图型展示使用grafana等。

也可以使用公司自研的数据采集和展示系统。

平台化

需要满足的需求多租户和组件化。

多租户是为了让压力测试平台供多人使用,也可以做到用户间测试资源进行隔离和共享。

组件化,是为了让通用的压力测试平台更简单地支持更多c++在线服务。具体的的实现方法如下:

  • 平台定义组件的统一接口,建立调用框架。
  • 不同组件依据平台的统一接口,定义自己的接口实现,并编译成为动态链接库。
  • 平台通过加载组件的动态链接库,实现面向不同服务的流量录制与回放。

当前问题总结

专用工具和通用压力测试工具的优劣对比

多个团队各有一套测试工具,统一起来有一定难度