看到《每个人都是年少的奴隶》这个影评,颇有感触,记录一下。
作者归档: 童燕群
Home-Server磁盘降温记
由于内存不足,Home-Server上面运行的虚拟Windows主机经常宕机,就想着给Home-Server更换一根16GB内存。小机箱内部空间狭小,部件接合紧密,拆机时把机箱风扇给扯断了。费了老大的劲儿,内存条是装上去了,开机也能识别,但是少了个风扇。
当天晚上,重新还原各个部件到机箱内部,后来太晚了,机箱就没有封盖,准备第二天早上再弄,心想少一个机箱风扇应该也没多大事。结果,第二天早上,准备关机装机箱盖,运行了一晚的服务器,发现磁盘烫手,都有开水的温度了。不对劲,赶紧安装hddtemp检查磁盘温度,发现竟然达到70多度。这样太危险了,影响磁盘寿命,赶紧某宝下单一个宣称4K转速20元包邮的机箱风扇(最终实际能跑到3100转,但是已经够用了。)。历经3天,快递终于到了。装到机箱后,默认是自动调速模式,声音大的有点像置身机房,这样放在家里,肯定难以接受。研究了半天,将/sys/class/hwmon/hwmon2/pwm1_enable置为1,然后设置/sys/class/hwmon/hwmon2/pwm1的值尽可能小,以降低转速,发现最小转速就是1500多,再小风扇就停止转动。1500转,声音小多了,噪音可以接受了,温度也还正常。
在这个过程中,还研究了一下使用Grafana监控磁盘温度的方法,Prometheus官方提供的node-exporter没有提供hddtemp相关的功能,找了半天,也没有人提供能用的基于hddtemp的监控exporter,于是写了一个循环运行的Shell脚本+PushGateWay实现了一个磁盘温度的exporter。
经过一番折腾,磁盘温度降到能接受的40度左右的范围了,对比效果见下面的监控图。在没有风扇的时候,发现不仅磁盘温度非常高,磁盘温度还会将CPU温度拉高。把磁盘挪开,则CPU温度在正常范围。SAS盘温度高真不虚。这次拆装机颠覆了我对磁盘温度的认识。之前一直认为磁盘运转过程中不需要风扇,机箱风扇是给整个机箱内部的除CPU外的部件散热,但重点不是磁盘,没想到在小机箱里面磁盘是发热量的大头。
介绍一个照片管理工具:PhotoPrism
最近发现一个跟jAlbum功能高度一致的相册工具,PhotoPrism,安装步骤不复杂,这里不作介绍。准备拿来跟jAlbum对比一下。看了官网的Demo,发现跟我之前做jAlbum时预想的功能完全一致:照片分类、人脸识别、照片日历还有照片打Tag,最重要的是,我一直不会做的界面,这个工具的要好用很多。赶紧docker安装试用了一下,挂载Home Server下的图片目录,在照片比较少时,完成加载很快,但是照片一但多了,就很慢。下面从各个维度对比一下,以打分的方式比较 :-)
比较项 | jAlbum | PhotoPrism |
人脸识别 | 借助于第三方系统,识别精确特别是人脸对比方面精准。 5分 | 使用Pigo,All In One的方式,识别准确率较低。 3分 |
图片场景识别 | 不支持 | 支持识别图片场景,自动打标签,准确率不高 3分 |
备份照片到远端 | 支持对象存储(华为OBS和Amazon S3) 4分 | 使用Webdav协议备份。某些云盘支持WebDAV,因此可以网云盘备份照片。 4分 |
视频管理 | 支持 4分 | 支持,支持从照片中抽帧并做图片分析。 4分 |
界面 | 简陋 2分 | 界面精美,动态页面非常好用,支持编辑元数据,指定人像名字,编辑人像。 5分 |
客户端 | 浏览器 | 浏览器,有准备推出手机端的应用。 |
自动识别新增文件 | 支持 4分 | 需要手动点击分析图片文件按钮。 2分 |
支持上传照片 | 不支持 | 支持 |
支持自动备份手机照片 | 不支持 | 不支持 |
访问安全 | 支持简单的发放Token方式,支持Https | 支持单账号登录。 |
照片分享 | 不支持 | 支持 |
功能定制 | 支持通过服务端参数定制很少的页面行为。 2分 | 支持在界面配置各种功能。 5分 |
性能 | 流畅 4分 | 页面响应明显卡顿。 2分 |
技术栈 | Java、少量JS、处理EXIF信息、FFmpeg、SQLite。 更多依赖第三方服务。 | Golang、Vue.js、SQLite、处理EXIF信息、FFmpeg、WebDAV。 All In One,几乎不依赖第三方 |
开发规模 | 个人玩具 ^_^,16年基本完成,后面没在大规模开发。 | 形成规模的开源社区,多人协作开发,正在商业化的路上。18年开始在Github开源,具体开始时间不详。 |
自制一个动态域名解析系统
之前一直用路由器自带的动态域名解析(Dynamic DNS,DDNS)系统,一般路由器自行提供一个,或者直接对接花生壳。路由器自带的几乎不能登录,花生壳也是经常性的退出登录,或者直接把域名解析为127.0.0.2,遇到好几次了,难以忍受。仔细研究了一下百度云的域名服务,希望找到一个能够通过远程调用设置A记录的入口。找到了这个介绍链接:更新域名记录,使用百度云的域名解析服务的API可以实现对域名解析的各种远程操作。首先在《HomeNAS IP地址变化》中介绍了如何获取本机真实IP的方法,然后当监控到IP发生变化时,调用API设置A记录即可。本来想使用Python SDK简单写几行脚本直接运行起来就好,结果百度云域名服务的Python SDK以及给出的几行样例代码漏洞百出,没法实际运行起来。只能做个Java Jar包供命令行调用了。这样终于搞定了一个可以长时间稳定运行的DDNS实现,一个完美的花生壳替代品。
先列举所有主域名的解析配置,找到需要修改的那一项,然后使用列举得到的ID设置新的IP地址即可。详细代码参见如下工程:https://git.codefine.site:3000/Shentar/setdomain2
关于父子进程信号传递、Shell进程退出等问题
我们通常都有这样的经历,用shell启动一个业务运行着,在终端界面上按下ctrl+c后,发现还有脚本启动的后台任务仍在运行。或者是出现另外一个方面的问题,本来希望进程安全在后台运行,退出了当前界面后,后台进程也跟着退了。关于这里第2个问题,之前有一篇博客讨论过:让进程在后台可靠运行的几种方法。今天我们探讨第1个问题,怎么让父进程(主shell脚本)退出时子进程(shell脚本中启动的所有后台任务)也退出。
我们知道当子进程退出时,父进程会收到子进程退出时发送的信号,进而做一些处理,如,父进程为守护进程的话,会重新拉起新的子进程。在shell中,我们一般使用wait命令来等待所有当前上下文中启动的后台任务。因此做如下实验脚本。
jAlbum升级JDK、Jetty和支持HTTP2
利用这个周六休息时间,将jAlbum代码升级了下。主要是想支持HTTP2,提升浏览器加载性能。升级过程中遇到一些问题,记录下:
1、alpn库的问题,jetty在配套不同的jdk版本时,有一些策略:见官网链接的说明:Jetty 9 and ALPN,jdk8使用一个单独的包,jdk9及以后的版本使用使用alpn的api,需要另外一个包。在不同的jdk环境下,依赖包有差异,不能混淆。
2、jar-with-dependencies 和 META-INF/services 冲突的问题。大概是jetty-http和jetty-http2包内都实现了同一个接口,而jvm只加载到了其中一个:
org.eclipse.jetty.http.Http1FieldPreEncoder
org.eclipse.jetty.http2.hpack.HpackFieldPreEncode
两个类都实现了同一个接口,使用了META-INF/servcies目录的机制。由于之前打包时,使用了将所有依赖包都抽取到一个独立jar包的做法,导致这个servcies目录下的同名文件只保留一个,最终http2的类无法加载成功。改用依赖包放在单独目录的方式,解决问题。
3、升级jdk到11之后,有几个原本是jdk自带的工具包(jaxb和anonations)被新版本jdk删除了,只能一一重新在pom.xml中添加回来。
本来支持http2是个比较简单的事情,由于这些库之间的互相依赖,折腾了比较久。具体修改:Commit记录。也编译了0.3.2版本放在版本下载表中。升级改造之后jAlbum、本站以及相关的子站点都全面支持HTTP2。
一道有趣的并发编程试题
今天看到《如何优雅的让3个线程打印ABC》这篇文章,就像文章里讲到的,3个线程顺序打印ABC确实没有必要,很浪费,单纯考察多线程的控制机制,面稍微有点窄,也是挺鸡肋的。实际上,既要多线程并发执行,又要输出结果有序,这样的场景还真有,类似于存储系统里面的单个文件顺序存储,但是又要支持多个客户端并发写,即:多个线程并发提交IO,由一个类似于总线的机制排序,打包,按包写盘,完成后同时通知各个等待响应的客户端。这里不打算介绍复杂的IO逻辑,想拿一个简单的模型来实例解读一下。
在之前公司经常给面试者出一道题:计算 [10亿, 12亿) 范围内的质数,要求:
- 使用多线程并发计算
- 边计算边输出,按照从小到大排序输出
- 内存使用量越小越优,已知的可用内存量不足以存储所有计算结果
- 耗时越短越优
同上面的题目一样,没有华丽的算法,简单考察应试者对多线程的理解和编码能力。但这道题比上面题目要更注重实用,并不是为了多线程而多线程,并且多线程能真正起到性能提升的效果,上面的ABC只是借锁来串行化了任务执行过程,严格意义上讲,不能算是实用的多线程实例。
下面给出思路,质数计算有一定的工作量,并且随着数字越大计算量越大,题目要求的计算范围很广,因此可以简单的以数字为单位分给多个线程去运算。
尝试写了一版,发现结果队列中的记录积压严重,调整线程池的大小也无济于事。这个并发模型用得不对,用LinkedBlockingQueue仅仅解决两个线程之间的同步,可能太浪费了。take调用的开销应该太大了。
HomeNAS IP变化规律
成都电信分配给个人的家用宽带IP地址定期更新,本来是用来快速发现变化后的IP地址的一个任务,解决IP地址变化后需要15分钟才能登录的问题,结果让发现了IP地址变化的规律。每隔6天,在每天中午11点20后的一个小时内更新IP地址。不知道是只针对特定账号的任务还是所有人同一时刻变更。
分享一个实时抓取IT相关博客和新闻的业务
一直通过TTRSS订阅各大IT门户和博客的文章,其实这些内容更适合公开访问,于是简单做了个页面,后台通过java程序直接访问TTRSS的数据库生成页面。内容不是全网爬取的,是定点几个比较大的门户网站的,搜索条件比较简单,通过关键词过滤内容或者标题。后台准实时拉取各个Feed的文章,然后定时半个小时刷新一次页面,半个小时内,网页呈现都是缓存的内容。因为爬取数据的过程是现成的,主要工作是做个动态页面,几个小时就搞定了。程序放在家里的NAS上面运行。
我的2020
2020年于我,可能是以后回忆里记忆最深刻年份之一。就像2002年的焦灼的高考录取、2008年坎坷的毕业和华为入职、2012年差点变成我人生真实的世界末日,之后来到成都,继续华为的工作,后面几年并没有大风大浪,似乎平静了许多。直到2020年,突然发现时光流逝得如此之快,让人猝不及防,都已经快走到个人职业尽头了。经过几次外部接洽,终于下定决心,不能再这样下去,离开华为,重新开始。
华为带给我的东西,除了劳动所得,其他并不多,有用的积累都是自己工作之余完成的。如果说华为工作的优点,我觉得最重要的是规范、责任和质量意识。对于自我约束力强的人,用强大的制度帮助个人形成这些习惯并不太需要。现在跟人聊起华为时,一般都会说,华为不适合久待,除非能在华为的制度与灰度之间游刃有余,并且进入利益核心里面去,否则应该越早离开越好。
华为只关注公司的发展,不关注个人,为了达到目的,可以不择手段,因此培养出来了很多一方面严格遵守规则,一方面又在规则照顾不到的地方肆意妄为。一个简单的例子,你很难想象,这样一个绝大部分员工都来自重点高校毕业的公司的洗手间,无论什么时候总有轻量级代谢产物越界到蹲位前,尽管清洁工频繁清理,总能遇到。心声社区都看到过多次批判这种行为的。
所谓的狼性,其实就是只关注食物,只要能抢到食物就行,与人性是对立的。有人解读狼性是群体行动,讲究合作,其实还是只关注目标,最终还会出现狼之间互咬。 任老板无时无刻不在宣扬一种悲情观(危机意识?),让大家始终绷紧弦。公司不断积累,所有员工都在尽最大努力工作,于国家民族当然是好的,现在正是需要奋斗的时候。但是对于更希望实现自我发展和抱负的同学就未必是好事了。公司的文化决定了管理方式,而华为的管理方式正是让每个人都全身心投入,一刻不停地工作,没有任何时间思考,一旦有同学有想法,有更好的方向,管理者就会利用内部环境封闭,内外部信息差,来说服员工,非常容易奏效。听的最多的是现在外面环境差,出去不好;你看某某,他去年收入还不如你,现在多高了;屡试不爽。
看透这些的同学总结出了三个字的华为定律,忍狠滚,确实如此,每个人都在这三个状态之间挣扎。甚至陷入循环。在华为时想的最多的就是这样的日子什么时候是个尽头。终于,我也走出了这一步。现在想的最多的是,只要出来了,就还有机会!:-)
本来想写一下2020年的总结,结果成了华为吐槽贴,也算是给十二年的华为职业画上一个句号。作为成功的公司,成功的事业,必须要有人为此付出,甚至牺牲,但是能否找到更好的平衡点呢?希望自己在逐步接近这种理想状态。