如何开发FoloToy玩具可以使用的私有 STT/LLM/TTS 服务

FoloToy AI 玩具是如何工作的? FoloToy 出品的所有玩具(包括电路板)作为客户端连接玩具服务,玩具服务我们提供了folotoy-server的docker自部署镜像,可以轻易的部署在各种 Linux 发行版系统上,包括 Debian/Ubuntu/CentOS等等,自部署镜像配置下载地址为: 自部署镜像:https://github.com/FoloToy/folotoy-server-self-hosting 部署教程:https://docs.folotoy.com/zh/docs/installation/start 玩具服务 folotoy-server 主要由以下3个部分组成 语音转文本:服务程序通过互联网接收玩具发送的实时录音数据,并调用 STT(声音转文本)API 将声音转换为文本。目前支持的 STT 选项包括:openai-whisper、azure-stt、azure-whisper、dify-stt、aliyun-asr 等,点击查看支持的STT完整列表。 调用大模型生成文本:在接收到上述文本后,立即调用 LLM(大型语言模型)API以流式方式获取 LLM 生成的句子。然后,调用 TTS(文本转语音)API 将句子转换为人类语音。目前支持的 LLM 选项包括:openai、 azure-openai、gemini、qianfan、dify或由 One-Api 代理的 LLM,以及与 OpenAI 接口兼容的其他大模型服务,如 moonshot 等, 点击查看支持的LLM或者Agent完整列表。 文本转语音:玩具将接收由FoloToy服务器生成的 TTS(文本转语音)音频文件流,并按顺序播放它们。目前支持的 TTS 选项包括: openai-tts、 azure-tts、 elevenlabs、 aliyun-tts、dify-tts、edge-tts(免费)等,点击查看支持的TTS完整列表。 FoloToy AI玩具调用的接口,支持了LLM行业的通行的做法,即完全兼容 OpenAI 的接口,在了解工作原理之后,只需要提供 OpenAI 接口格式相同RESTful接口,给folotoy-server调用,就能实现让玩具使用自定义的STT/LLM/TTS服务,如图所示: 接下来介绍如何实现蓝色圆圈的部分服务 实现和调用自定义服务 实现支持 OpenAI 接口的自定义服务之后可以通过修改 docker-compose.yml 或者 roles.json 文件来调用。docker-compose.yml 为修改全局变量,roles.json 可以针对角色进行修改,roles.json 配置的优先级高于 docker-compose.yml。 自定义 STT 服务 接口说明 自行实现 STT 服务 RESTful 接口说明,详情请参考 OpenAI STT 接口:https://platform....

August 10, 2024 · 2 min

我的推特账号 lewangdev 终于解封了

我的推特账号 x.com/lewangdev 终于解封了,从去年8月17号一直封到今天,已经差不多快有 6 个月的时间。在这 6 个月里,除了今年 1 月份,我每个月都写了一封申请解封的邮件,前几个月全部都是使用 ChatGPT 写的英文版解封申请,就在去年12月份的时候,想想自己莫名其妙被封确实有点恼火,于是用中文写了一封解封邮件,并且提到封我的账号是否是因为审核人员有种族歧视。以下是我的邮件内容: Hi, 已经过去四个月了,我的账号 lewangdev 还是被冻结着的,真是太难熬了。我翻看自己的推文,始终认为我没有发布任何破坏了推特的规则的推文,冻结我的账号一定是一个误会。 我已经使用这个账号十多年了,一直在个人使用,我的账号被冻结不仅是我感觉到惊愕,我的所有朋友们都觉得太莫名奇妙了,让大家都觉得推特平台怎么会这样不确定。 另外我不知道你们为什么会封禁我的账号,是因为我一个亚洲人吗,如果不能给出冻结我账号的明确理由,我非常怀疑你们的审核人员是否有种族歧视。 请帮我解封账号,或者给出明确的冻结理由。 谢谢 到现在我都不知道我的账号为何被封,被举报还是被误杀?也许就像能哥说的,是马斯克在搬机房的时候弄坏了我的数据。看到能哥的说笑我还真可找到了可疑的证据: 账号被封之后几天,我发的推文里面的图片链接都挂掉了。 不过在我收到的解封邮件里,推特还是告诉了我,被冻结是因为违反了平台的4条规则,我确信我都没有做过。以下是推特解封邮件提到的我违反的规则: Sending multiple unsolicited @replies or mentions. Learn more. Posting multiple unrelated updates to a trending or popular topic. Learn more. Aggressive and random repost and/or liking posts from other accounts. Learn more. Misuse of X product features This includes any of the following: “follow churn” – following and then unfollowing large numbers of accounts in an effort to inflate one’s own follower count; indiscriminate following – following and/or unfollowing a large number of unrelated accounts in a short time period, particularly by automated means; and duplicating another account’s followers, particularly using automation....

January 31, 2024 · 1 min

无用却能让我快乐的小事——改图标

最近几天连续做了几次改图标的事情,非常无用却令我开心。 给 Alacritty 换个图标 新安装了 Alacritty 这个终端,Alacritty 什么都好,就是图标我感觉太丑了。之前看到 @hitw93 的博客提到给 Alacritty 更改了图标,我照葫芦画瓢,做了红绿蓝三种颜色的终端图标,替换之后,每次在切换 app 或者在 Lanuchpad 页面看到它的图标时候,都会惊叹自己太有才了,心满意足。我制作的图标和替换方法都放在这里了:Alacritty.icns。 另外 Alacritty 也支持了背景模糊,这个功能我等了很久,不用担心截图时候把背景也显示出来了。 给输入法鼠须管 Squirrel 换个系统托盘图标 然后就是修改 rime 输入法鼠须管 Squirrel 的系统托盘图标了。macOS 在 Ventura/Monoma 系统之后,把输入法的图标由方形变成了矩形,在用 Ventura 或者 Monoma 选择输入法的时候,列表中那种不一致的感觉真让人难受,于是我去rime项目的仓库里搜索了一下有没有报过这个问题,果然有人与我的感受是相同的,我找到了修改图标的 PR,终于所有的输入法图标都一致变成矩形,看起来舒服了很多。 替换步骤: 打开目录 /Library/Input Methods/Squirrel.app/Contents/Resources 下载 rime.pdf 把目录下的 rime.pdf 换掉 退出系统登录再重新登录 给 LaCie 移动硬盘换个图标 今天又做了件没用的事:给移动硬盘换图标。买了块 SATA 口的 SSD,替换已经吃灰多年的 LaCie 移动硬盘里面的机械盘,替换完插到电脑上发现 LaCie 图标竟然没了,于是去官网搜了一下,不愧是法国的公司,管他性能怎么样,首先是要好看,所有产品的 icns 图标都可以下载,并且写清楚了怎么替换。图标和替换方法在这里:LaCie Drive Icons 现在好了,电脑里看得见的地方都满意了,虽然没啥用,却能让自己快乐事,为何不去做。这可能是细节控,每一个做产品的人大概都很注重细节,但是细节在一些情况下也需要妥协。 还是一件小事,我在发推特的时候会遇到:发推时是否需在英文单词的左右添加空格。我虽然有蓝标,但是我还是希望我的推文尽量只用一条并且能在 280 个字符以内,这样不会被折叠起来。如果提炼推文之后字数还超了,手动输入的空格明显就是浪费了,所以字数较少的推我会加空格,字数较多的推文我会去掉空格。 就这样,我经常会折腾一些无用的事,想一些无用的问题,但是能给我带来快乐。

January 11, 2024 · 1 min

Kindle 中国停止运营,一键下载已购买的电子书

前几天亚马逊宣告 Kindle 中国电子书店运营进行调整,通知标题写得比较委婉,其实就是亚马逊电子书即将退出中国市场,到时候我们购买的国行版 Kindle 将不能购买新电子书,也不能下载已经购买的电子书了。 如果购买的电子书比较多,手动一本一本的去下载是挺费时间的,我来分享一下我是如何使用 Python 一键下载所有电子书的。 安装 Python 用 Chrome 浏览器打开 https://python.org,下载最新版本的 Python 3.10.4 下载好然后运行 python-3.10.4-amd64.exe, 选择第一个选项,一定要记得勾选添加到 PATH,否则在命令行中执行 python 时会报错。 准备 Python 一键下载脚本 用 Chrome 浏览器打开 https://github.com/yihong0618/Kindle_download_helper,下载 ZIP 包后并且解压: 使用 Python 一键下载脚本 进入解压后的目录,点击鼠标右键打开一个命令行窗口 打开的命令行窗口是这样的: 接下来准备 python 的虚拟环境,在命令行窗口输入: python -m venv venv 创建好虚拟环境之后,再激活虚拟环境,在命令行窗口输入: .\venv\Scripts\activate.bat 安装 Python 脚本的依赖库,在命令行窗口输入: pip install -r requirements.txt 至此,一键下载脚本准备就绪,在命令行窗口输入: python kindle.py 这样看到了脚本的帮助提示: 接下来我们准备脚本需要的 cookie 和 csrf_token, 这两个值都需要通过 Chrome 浏览器获取。 获取 cookie 和 csrf_token 首先使用浏览器登录亚马逊账号, 登录地址 https://z.cn, 登录之后访问 https://www....

June 6, 2022 · 1 min

写个程序把油管 YouTube 变成无限容量的网盘

前几天刷新闻的时候,看到了一个代码仓库 YouTubeDrive 的介绍,他的作者在多年前用 Wolfram 语言(也就是 Mathematica) 编写了一段代码,可以将油管变成一个无限容量的大网盘,看完介绍之后我脑子里直接蹦出无数个“卧槽”,心里顿生“这样也行”的膜拜之情,不禁提问:这个是薅羊毛的最高境界吗? 说起 Wolfram 语言和 Mathematica,不得不提一下,它是我学习的第一个编程语言(汇编是第二个)。多年前我是在学校机房学的,当时只用它画画数学公式的图,今天看着 YouTubeDrive 的实现,才了解到 Wolfram 还可以这样用。 首先,和原作者一样,我也不提倡这样把 YouTube 当成一个无限容量的网盘使用,相同的道理,我也不提倡在国内把 B 站或者任意视频平台当做位无限容量的网盘来用。 昨天在看完 YouTubeDrive 源码之后,想着要不我也用 Python 实现一个,正好傍晚溜娃的时候,啥也不能干,就边走边想,我用 Python 应该怎么来实现一个? 在坐着等娃的时候,就用手机查下资料,大概了解了一下 numpy 和 opencv 的使用,晚上吃过晚饭就开始写了,很快也实现了一个可以工作的 Python 版的。 我觉得这个想法还是挺有意思的,虽然不太靠谱,但是真的好玩。不想去读 Wolfram 源码的朋友可以看看我接下来的分析,看看是如何把文件变成 YouTube 视频的进行存储的。 磁盘上的文件是什么 在我们的计算机(无论电脑还是手机都是计算机)磁盘里,存放了很多很多的文件,例如图片,文档,视频等等,每种文件都有自己的类型,或者叫格式,一般我们都会给文件添加一个后缀名展示文件的类型,但是对于电脑而言,无论是什么文件,它都只是由比特(bit) 0 和 1 组成的数据。 例如这张图片: 用 vim 执行命令 :%!xxd,打开是这样的: 图片文件的头 4 个字节是 ffd8(其实 ffd8 说明了这个是 JPEG 格式的文件),ffd8 是 16 进制的表示法,比 2 进制看起来更清晰。 在计算机里,用 8 个 bit 表示一个 byte,即 1 个字节有 8 位,一个字节需要用 2 个 16 进制数来表示,例如:ffd8 是 2 个字节。...

May 27, 2022 · 1 min

如何打造国内开发所需要的网络

本项目正在调整,请稍等再使用 一个对国内开发者可能有点用的网络工具,cndevnet 帮助开发者,尤其是初学者不用再费心折腾 pip/npm/golang/flutter/android/blockchain 等等无法访问的问题。 背景 由于某些原因,国内开发者需要的不少技术站点或者镜像源都无法直接访问,这使得在开发者在日常工作中会消耗额外的时间,去设置各种代理或者寻找国内的可替代的镜像源来使用。 在开源软件的世界里,几乎所有的知名项目,原本只要把代码 clone 回来,不需要做额外任何配置,只需要按照它的说明就可以直接编译源码。但由于网络的原因,在国内甚至连开源软件的源码都不太方便直接下载,一些原本只需要从 GitHub 拉下来代码就可以直接编译成功的项目,在国内也是连编译都编译不过。 国内开发者群体是非常庞大的,所以我看到了很多知名的开源项目为中国用户在 README.md 文档或是页面的显著位置都增加了中文提示,去引导国内开发者去使用国内的镜像。 Flutter powerlevel10k 但是,我想这种做法应该不属于 i18n,因为我很少看到有引导日本的开发者去用日本的镜像,或者引导德国的开发者去用德国的镜像,这看似解决了访问慢或者无法访问的问题,但其实是加剧了国内开发者与全球互联网的割裂,在开发者的世界里面,也形成了国内和国外两个网络。 给系统或软件单独设置代理,或者寻找国内的可替代的镜像源我都觉得不是一个好方案,因为这样在国内的你总会遇到各种各样的国外开发者就不会遇到的问题,最好还是能够拥有一个与国外开发者“用起来”好像是一样的网络环境。 cndevnet 就是为了解决这个问题而创建的,希望能帮助到和我一样遇到相同问题的国内开发者。 从 Linux 开始 cndevnet 可以在 Linux 环境下搭建一个专为初学开发者设置的开发网络,搭配使用 vscode 进行远程开发是一种不错的体验,适合学习 python/golang 等。 Linux 环境可以是在国内云平台上的一台云主机,也可以是运行在本地虚拟机里面的主机,或者是局域网中的一台 Linux 主机。 Debian 是一个非常棒的 Linux 发行版,推荐希望学习 Linux 的初学者使用。如果希望使用带有图形界面的 Linux 系统,Ubuntu 也是一个非常好的选择。 cndevnet 使用了以下软件和服务 Debian:目前支持的 Linux 系统 Docker: 用于运行 gost 和 smartdns 服务 gost: 用于建立 WSS(Websocket over TLS) 服务 smartdns: 用于解决 DNS 污染 dnsmasq-china-list: 国内域名 Cloudflare IP Range: Cloudflare 的 IP 范围 Cloudflare: Cloudflare 的 WSS 代理服务 Oracle Cloud: Oracle Cloud 的云主机 cndevnet 原理 cndevnet 通过 iptables 等工具和数据实现了系统的透明代理,由于是系统级的透明代理,所以在启用了 cndevnet 的 Linux 系统上,是不需要为系统或者各类开发工具或者服务单独设置代理的。...

May 16, 2022 · 1 min

写了一个 ShadowsocksX-NG 的 gost 插件

gost 是一个非常有用的网络工具,可以在 ShadowsocksX-NG 中安装 gost 插件,方便在 ShadowsocksX-NG 中使用 gost。 原由 自从查资料上网工具换成 gost 之后,由于 MacOS 上没有 gost 专用的智能代理(也就是该翻的时候翻,不用翻的时候不翻)桌面客户端,所以需要用 gost 在本地把 wss 代理转成 ss 后再继续使用 ShadowsocksX-NG。 虽然可以用 launchctl 启动一个 gost 后台服务,但是用起来还是不太方便。 看了下 ShadowsocksX-NG 是如何工作的: ShadowsocksX-NG 会在本地启动 ss-local 进程跑一个 socks5 服务,而且 ShadowsocksX-NG 实现智能代理的逻辑与 ss-local 并没有太多的关系,所以只要在想办法本地能提供一个 socks5 服务就够了。 于是写了以下脚本替换了 ShadowsocksX-NG 安装目录下的 ss-local(替换之前要备份一下这个文件) #!/bin/sh - #/opt/gost/gost -L=sock5://:1086 -F=wss://username:[email protected]:443 # Use gost.json #{ # "Retries": 3, # "Debug": false, # "ServeNodes": [ # "socks5://127.0.0.1:1086" # ], # "ChainNodes": [ # "wss://username:password@1....

December 2, 2020 · 1 min

机房不能访问互联网,轻松搞定系统部署

创业这段时间以来,我们的 IoT 系统已经在不少客户的机房做了私有化部署,客户大多都是机加工厂、商业大楼、医院和大学实验室等,客户的机房都有一个相同的特点:私有云,与外网隔离,不能访问互联网。或者更为准确的说,是我们部署的服务器不能访问互联网,在没有互联网访问权限的情况下,系统的包管理工具(yum/apt/docker)都无法使用了,在这种情况下进行系统部署安装,费时费力,而且无法进行远程部署维护,也大大增加了项目的实施成本。 在最近的一个客户项目的实施过程中,看到客户的一些其他供应商在系统部署过程中非常艰难,甚至是 CentOS 系统初始化和 Docker 的安装就花掉了两个礼拜的人力,不排除一些供应商这样折腾会给他的客户留下工作敬业钱花的值的好印象,但对于我们这样的小创业公司来说,这样的时间浪费和低效是无法承担的成本,因为来实操部署的人就是公司老板本人了,我也不想出差在客户这里待上两个礼拜。 在工作完成之后,想想可以把解决问题的方法记录一下,也许能给遇到相同问题的同行一些启发和帮助。好了,废话不多说,接下来我们就来解决这个无外网的部署问题,顺便再解决一下远程维护的问题。 一、面临的问题 在部署和维护一个私有化企业内部使用且无互联网访问的系统中,可能会面临以下问题: 机房服务器无法访问 Internet 可通过接入企业内网来访问服务器,而从服务器无法直连办公室网络,即机房和办公室在不同的网段 无互联网访问权限的情况下,无法直接使用系统的配置工具,如 yum/apt/docker 等,配置系统和部署服务费时费力 无法远程进行维护 客户内网拓扑示意图,此处省略了防火墙,简化拓扑图的复杂度,如下: 网络拓扑图说明: 机房和办公室不在一个网段 机房网段假设为 172.22.0.0/16,办公室内网 WiFi 的网段为 192.168.137.0/24 机房服务器之间是互通的,办公室可以 ping 通机房服务器,在机房服务器上无法 ping 通办公室部署控制主机,这里假设办公室网络作为一个 NAT 放在上层交换机后面 内网没有互联网访问权限,包括机房服务器和办公室内网 WiFI 二、解决问题的方法 既然是由于机房服务器没有互联网访问权限,不能联网下载安装包,那就想办法让机房服务器可以连接互联网或者搭建内网的软件包镜像服务,于是想到一些方法来达到目的: 告知客户问题,申请开通互联网访问权限,可以限定为指定的网址和协议(HTTP/HTTPS),需要远程维护的化,还需要申请可以连接到服务器的 VPN。这个方法在需要客户的进行审批,可能时间比较长。我们的客户中有不少都没有自建 VPN,或这不方便给我们开通 VPN,另外也无法开通需要我们部署的服务器的互联网访问权限,所以不能使用这个方法 在客户机房放置可以通过 4G 上网的堡垒机,堡垒机接入客户机房网络。在客户机房放一个堡垒机,虽然说是堡垒机,但可能客户那边的机房管理也还是不容许放置这样的机器的,所以也不能使用这个方法 搭建 yum(CentOS)/apt(Debian/Ubuntu)/docker 的内网镜像服务,搭建内网镜像服务可能就是一个比较艰巨的任务,难以接受给自己又添加了一个艰难的任务,此方法也作罢 通过在办公室网里放置部署控制机,同时连接内网和 4G 路由器提供的外网(互联网),在部署控制机上搭建 SDWAN 或者 HTTP 代理,yum/apt/docker 都支持 HTTP 代理,这样修改系统配置之后,就可以通过代理安装部署服务,这个方法比较简单,而且几乎不需要客户的参与就可以完成。不过也有一些前置条件,例如: 办公室中主机可以接入客户网络 客户服务器允许办公室网络中主机通过 TCP 或者 UDP 访问其任意或者指定的端口 客户办公室的 4G 网络信号要足够好,这样可以提供更好的外网速度 拥有服务器的 root 管理员权限(需要安装软件和修改系统配置) 通过权衡利弊,我们最终使用的是第 4 个方法来搭建的,下面来讲讲搭建的过程。...

November 27, 2020 · 5 min

大象(Gradle)的故事:一见如故

小码哥:“与大象(Gradle)一见如故?你就是 Gradle?” 大象:“对,我就是那个用来构建 Java 项目的 Gradle 大象。 ” 小码哥:“我好像天天都在用你啊。看,我的项目都是用你构建的。” 大象:“但你不一定真的认识我,你每次修改点构建代码时是不是都要问下谷哥哥(Google)或溢栈哥哥(StackOverflow)?” 小码哥:“额。。。” 大象:“我是你的老朋友了,不要天天如初见哦,咱们得多聊聊,我爸妈给我写了传记(文档),估计你也懒得细看,不如我给你做个自我介绍吧。” 小码哥:“👌ok” 大象:“你有用 InteliJ IDEA 吗? ” 小码哥:“对,用的社区版。” 大象:“那我就用 InteliJ IDEA CE 版来给你介绍自己”。 你好,我是 Gradle! Gradle 是一个用来自动化构建项目的的工具,可以用来构建你常用的 Java、Kotlin 等 JVM 语言开发的项目。我的配置文件可以使用 Gvoovy 或者 Kotlin 来编写,不像隔壁前辈 Maven 那样,要写一大段 XML,你可以很开心的像写代码一样来调整我的配置。 其实我就是你的代码自动化产线,产线有几个工序(Task),你负责喂我代码,我负责打包(Jar/War/JavaDoc/Test)。是不是觉得与科幻片里面的工厂很像? 创建项目 请打开你的 InteliJ IDEA CE,使用 idea 可以很方便的创建一个由我构建的项目(File > New > Project…)。 这里在对话框的左边栏选择 Gradle,右边选择 Java 项目。 输入好项目名之后点击 Finish 就可以啦。 探索项目 idea 帮我们创建了一个 Java 项目,浏览项目很容易发现两个以 gradle 为结尾的文件: build.gradle 和 settings.gradle。我们来看一下它们俩的内容。 settings.gradle...

February 22, 2020 · 3 min

CentOS 7 上使用 pyenv 安装 Python 3.7.3

概要 本文记录了在 CentOS 7.6 系统上通过 pyenv 安装 Python 3.7.3 的过程。 环境 CentOS Linux release 7.6.1810 (Core) Kernel 3 3.10.0-957.el7.x86_64 Pyenv 1.2.11 安装 pyenv $ curl https://pyenv.run | bash 然后根据提示把以下内容放到 ~/.bashrc 文件末尾 # Load pyenv automatically by adding # the following to ~/.bashrc: export PATH="/root/.pyenv/bin:$PATH" eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" 安装 Python 3.7.3 准备 $ sudo yum -y install xz bzip2 bzip2-devel sqlite-devel gcc openssl-devel readline-devel zlib-devel libffi-devel 安装...

May 29, 2019 · 1 min

Java 进阶要点

自己学习 Java 和用 Java 过程中的理解和备忘的知识点。 JDK 11 Oracle 不在免费提供 LTS 版本了,包括 JDK 8 ZGC, 可伸缩的、低延迟的垃圾收集器,STW 时间不超过 10ms Nashorn 标记为 Deprecate 了 JDK 9 module try-catch 简化 _ 为保留关键字 var 将在 JDK 10 中作为关键字, 作为本地变量类型推断关键字 字符串相关,主要是 Compact String, 用 byte[] 替换了 char[], char 在 Java 中占两个字节 G1 作为默认垃圾回收器 JVM 启动 JVM 相关的命令行参数 G1 垃圾回收器 内存 JVM(Hotspot) 内存结构 制造各种 OutOfMemery 和 StackOverflow 各种 JVM 相关工具(jstat/jmap/jstack/jps 等) 解决 FullGC 的问题 引用:WeakRefrence/PhantomReference/SoftRefrence/FinalRefrence 等 ClassLoader/URLClassLoader Spring Boot 的 ClassLoader 自定义 ClassLoader 多线程和并发 JVM 的线程模型 1:1 协程 创建线程的方法 线程同步 synchronzied/对象锁/类锁/锁方法/锁锁代码块 线程池 锁相关(Lock 接口和实现类) Condition volatile ThreadLocal 用途和实现 并发(CAS/乐观锁/无锁/无等待/无阻塞) 字节码 基本结构 操作字节码的工具 Javassist/ASM AOP 集合 Collection,List,ArrayList,Vector,LinkedList, SkipList, Stack Queue HashMap/HashTable HashMap 扩容死循环问题 LinkedHashMap TreeMap HashSet,TreeSet WeakHashMap 并发相关的集合 ConcurrentHashMap CopyOnWriteArrayList IO IO 模型 NIO Non-blocking IO Java 8 IO 相关的接口和类 Netty Vert....

March 6, 2019 · 1 min

使用 Docker 方式安装 Gitlab,没你想得那么简单

为什么要写这篇文章? 曾经几年前在 Docker 还没有广泛应用的时候,在公司使用过源码的方式安装和升级过 Gitlab,虽远没有 Docker 方便,因为自己对 Linux 系统的理解,所以整体上感觉还是挺简单的。这几年随着 Docker 的普及,使得安装 Gitlab 更加的容易,不仅方便了我这样的老鸟,也更方便了小白用户们。但是 Gitlab 官方的 Docker 安装文档并没有写得很完善, 除了官方文档之外,检索出来的安装文档也是人云亦云,东拼西凑,结果也就是能运行起来,凑合着能用而已。避免出现下图中“我已经用 Docker 部署好啦”,其实已经翻车的情形。 我希望每做一件小事的时候也都能抱着“知其然知其所以然”的心态对待,用 Docker 方式安装 Gitlab,说简单来说就是一行命令的事儿,但是这样就够了吗?我看是不够的,所以就有了这篇文档。 本文需要达成的事项 在 CentOS 7 系统中安装 Docker 使用 Docker 方式安装中文版 Gitlab 和宿主机器共用 22(SSH) 端口 支持 SSH(22)/HTTPS(443) 方式推拉仓库 使用 SMTP 方式配置通知邮箱(腾讯企业邮箱) 改写默认的项目标签(Labels) 在 CentOS 7 系统中安装 Docker 这部分参考 Docker 的官方文档, 罗列一下安装步骤, 细节请看 Docker 的官方文档。如果使用 root 用户安装,sudo 可以去掉。 1. 删除老版本 Docker $ sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine 2....

December 18, 2018 · 4 min

日志收集和分析系统架构

背景 微服务,日志分散且种类多(php/java/python),用 docker 起应用,日志通过卷放在宿主机器指定目录下,服务有众多实例,metrics 数据也不仅相同,无论是日志还是 metrics 数据,都可以看作是时间序列数据 分散主要表现为: 多个主机 多个目录下多个文件 应用开发所使用的技术栈不同日志格式不同 web log(主要是 nginx) 各类事件 一些其它事务性的日志 日志为时间序列数据,包括: 系统日志: 各类系统产生的跟业务有关的日志或者与业务无关的日志 web 服务器日志:如 access.log/error.log 等有固定格式的日志 性能监控日志:打点记录各类服务的 metrics(全部为数值类型 long/double/bool) 系统日志 由时间戳、一些枚举值以及日志内容(变长字符串)组成 日志时间颗粒度:支持毫秒/秒 枚举值包括: [必选]主机名/host [必选]服务名/service [必选]实例编号/instance [必选]日记级别/level:info/debug/warn/trace/error 等 [可选]异常名/exception: 如果是异常,把异常名作为枚举值记录 [可选]线程名/thread: [可选]方法名/method: [可选]文件名/file: [可选]行号/line: 日志内容(变长字符串): 为实际记录的内容以及异常堆栈信息 web 服务器日志 access log(nginx) 日志内容:主要是文本(string)或者一些系统 metrics 数据(数值类型 long/double) 日志存储和处理: 数据磁带(1 周):kafka 提供热数据检索(1 个月):solr(or lucence based on cassandra) 日志存储(永久): kariosdb/cassandra: 支持 double/long/string 类型,kariosdb 相当于在 cassandra 上面套了一个壳,这样简化了很多时间序列数据处理的操作 数据展示:grafana,官方支持 kariosdb 扩展:数据深度挖掘分析 系统架构 特点:...

July 23, 2017 · 1 min

Log4j2 快速入门

背景 Java 生态下的日志库太多,配置也不同,大多数情况下会使用 SLF4j (又引入了一个库)来抽象日志接口。在使用 Log4j2 后,发现可以不使用 SLF4j 了,并且配置变得更简单,可以使用 lombok 的 log4j2 注解等。 需要搞清楚 如何设置哪些日志要记录下来 日志记录到哪里去 LEVEL 日志级别: 内置(有 Fatal):All < Trace < Debug < Info < Warn < Error < Fatal < OFF 还可以自定义: https://logging.apache.org/log4j/2.0/manual/customloglevels.html Appender: 日志输出的目的地 内置的目的地有: console, files(FIle/RollingFile), remote socket servers, Apache Flume, JMS, remote UNIX Syslog daemons, various database APIs … Appender 在接受到日志以后,可以通过级别过滤选择记录日志,具体配置: https://logging.apache.org/log4j/2.0/manual/appenders.html Logger 负责决定哪些日志要记录和发配日志 哪些需要记日志,设置什么级别,并且配置日志输出到哪些个 Appender 中去都在 Logger 中配置。Logger 有类似继承的关系,名为 Root 的的 Logger 为所有 Logger 的根,也就是说没有做特殊设置(additivity=false), 那么这个 Logger 的日志将会记录到自己指定的 Appender,并且也都会记录到自己所有“父” Logger 设置的 Appender 中去...

July 15, 2017 · 1 min

MySQL 数据备份和不停机重新搭建主从同步

背景 目前公司主要服务都是直接使用 MySQL 主服务器,从服务主要给离线数据分析服务使用,由于前期弄得比较简单的粗暴,从服务上还有一两个数据库在做生产使用, 并且从服数据已经不能和主服进行进行同步了,有大量错误,忽略都没有办法进行。此外,主服仅配置了三个核心数据的 binlog,随着业务的变化,其它数据库不能走主从这条路来同步数据,于是希望不停机的情形下重新调整主服配置,记录所有的数据库的 binlog,同时添加新的从服务器来同步数据 方案 1 MySQL 的主从是通过同步 binlog 日志来实现数据同步的,于是需要想办法把从服数据先于主服同步,记录 binlog 的 pos 值,再配置从服从该 pos 处开始同步,考虑可以使用 mysqldump 导出所有 innodb 数据,使用 rsync 同步所有 myisam 数据文件,然后再开启主从同步。但是目前这种方案不适用,主服不能长时间停机 方案 2 使用 xtrabackup 来完成目标 主从服务器上都需要安装 xtrabackup(实际使用 xtrabackupex): yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm yum install -y percona-xtrabackup-24 主服: 备份数据 # 注意数据库名称的转义,例如 - 号是 @002d innobackupex --defaults-file=/etc/my.cnf --socket=/var/lib/mysql/mysql.sock --user=root --password=xxxx --parallel=2 --databases="db1 db2" /data/backup/xtrabackup/ 保持事务一致 innobackupex --apply-log /data/backup/xtrabackup/2017-06-06_13-16-21/ 同步数据 rsync -avHz 2017-06-06_13-16-21 sysops@cow:/data/backup 从服: 修改 my.cnf 相关配置,恢复备份数据...

June 6, 2017 · 1 min

Nginx 性能调优「译」

这是一篇译文,原文链接:Tuning NGINX for Performance Nginx 为人熟知的是在负载均衡、静态缓存和 WEB 服务器等方面的高性能,目前世界上最繁忙的站点中大约有 40% 在使用 Nginx。绝大多数情况下,大多数默认的 Nginx 和 Linux 配置都可以工作得非常好,但也需要做一些优化以获得最好的性能。本文将讨论在优化系统时需要考虑的 Nginx 和 Linux 的部分配置。可配置的选项有很多,但是本文只涵盖推荐大多数用户调整的配置选项。本文没有涵盖的配置选项,只有那些对 Nginx 和 Linux 有了深入的理解的人或者获得了 Nginx 技术支持和专业的服务团队的推荐建议后,才可以考虑调整。Nginx 专业服务器团队已经为世界上一些最繁忙的站点通过优化 Nginx 获得了最高水平的性能,并且可以为任何需要获得自己系统最大产出的客户服务。 简介 本文假设读者对 Nginx 架构和配置的概念已有了基本的了解。Nginx 的文档内容将不会在本文中重复,但本文会提供各项配置简要的介绍和相关文档的链接。 在性能调优时,要遵循一个好的规则:一次只修改一个配置选项,如果这个修改没有在性能方面带来优化,那么要再改回默认值。 我们从 Linux 性能优化的讨论开始,因为 Linux 性能优化的一些值会影响到 Nginx 的一些配置。 Linux 配置 尽管现代 Linux 内核(2.6+)在各种配置情况下都工作得很好,但也有一些配置是想要修改的。如果操作系统的配置设置的太低,那内核日志将会有错误信息,从而得知哪些配置需要调整。Linux 性能优化可能涉及的配置有很多,这里我们只讨论那些优化达到正常工作负载最有可能涉及到的那些配置。调整这些配置请参考详细的 Linux 文档。 Backlog 队列 下面的配置选项与网络连接和其排队方法直接相关。如果连入率很高(译者注:客户端发起的连接很多)且系统性能配置不匹配,例如一些连接表现得有所停顿,那么修改下面得配置将可能有用。 net.core.somaxconn: 设置等待 Nginx 接受的连接队列的大小。由于 Nginx 接受连接非常的快,这个值通常情况下不用设置得很大,但系统默认值可能比较小,所以对于流量比较大的站点,增大这个值是个不错的想法。如果这个值太小,在内核日志中应该会看到错误消息,那么就需要增大这个值,直到错误消失。注意:若将这个值设置为大于 512 的话,那么需要在 Nginx 配置中修改 listen 指令的 backlog 参数来匹配这个数字。 net.core.netdev_max_backlog: 设置数据包在被发送到 CPU 前可被网卡缓存的速率。对于带宽很大的机器来说,这个值需要增大。可以查阅网卡关于这项设置的建议文档或者查看内核日志中此项设置相关的错误。...

October 16, 2014 · 2 min

使用 Vagrant 构建开发环境

Vagrant 是一个构建虚拟开发环境的利器,它使得在团队中很容易共享开发环境,有了它,不必每个人都搭建一个自己的开发环境了。在没有使用 vagrant 之前,我在 windows 中安装了 virtualbox,然后在 virtualbox 中安装了一个 ubuntu server。在 ubuntu 中安装了 mysql、jdk 等软件,并且设置了一个共享目录,以便于将工程代码直接共享给 ubuntu。在外部开发调试过程中(Java 项目),我需要在 virtualbox 中设置好几个端口映射,如 mysql,ssh 等等。这样在 cygwin 里面就可以通过 ssh 登录 ubuntu server 了,为了使得 ssh 登录不用每次设置密码,还需要手动生成公钥私钥。换机器了,这一切我又得重新配置。新同事来了,他也得像我这样重新配置一遍。有可能他还会有问题说:为什么按照你的说明,代码在我这里却无法运行呢? 一切都从 Yining 告诉了我 vagrant 之后发生了变化,原来一切都这么简单。 安装 VirtualBox Vagrant 其实是对 virtualbox 做了一层包装,它让使用 virtualbox 作为虚拟机更为简单。当然也可以使用 vmware,使用 vmware 那得找一个 license 了。 好吧,去这里 下载 VirtualBox。我使用的是 4.3.8 for OSX 安装 Vagrant 下载 vagrant 添加虚拟机镜像到 Vagrant vagrant box add vdevenv ~/Workspace/vagrant/boxes/vdevenv-0.0.0.1.box vagrant 的干净的镜像可以在这里下载: Ubuntu precise 32 VirtualBox Ubuntu precise 64 VirtualBox 更多镜像 在工作目录启动 Vagrant 进入自己的代码所在的目录,启动刚刚添加的虚拟机镜像...

March 3, 2014 · 1 min · Le

Python on My rMBP

前几天入手了一台 Macbook Pro Retina,把 BIG 提到了很爽的地步。经过几天的折腾,可以和 windows,ubuntu desktop 说 Byebye 了。之前整整用了一年的 Ubuntu 来工作,我用它来写 C、Java 和 Python, 要是 windows 没有 cygwin, 没有 MacType,那该多么恐怖。后来用了一段时间的 MBP,让我坚定了以后要自己买一个 MBP。 ubuntu 那么的惹人爱,因为它有个还挺好用的 GUI,从 debian 那继承过来的 apt-get, 一下子把一个从 redhat 9 用到 fedora 4 的穷学生拉到了 ubuntu 的阵营,至此,deskop 就被 ubuntu 占领了。在此之前,我还用段时间的 debian 和 gentoo。 不得不说,debian 太伟大太牛逼了,有一次要在一个 MIPS 的小设备上编译安装 erlang, openssl,libcurl 等做一些实验, 要跨平台编译这些软件安装到小设备上去,费了半天终于把这些都编好了,还写了一个编译脚步,结果 erlang 运行的时候虚拟机总是报错,也不知道怎么回事。后来注意到 debian 居然有 MIPS,ARM 的源,后来在 MIPS 设备上安装软件做实验,我再也没有遇到问题,一切都用 apt-get 搞定了。 除了 apt-get, 我想最令我惊喜还有 ubuntu 自带了 python 2.7,让我很容易在两台电脑之间拷贝文件:...

March 2, 2014 · 1 min · Le

阿里云和 ucloud 云主机评测

总体说明 我使用联通 10M 光网,SSH 在多个时间段登录两个主机都是非常的快,但是阿里云的 SSH 有时会断开连接,需要重新登录(一天遇到 n 次),ucloud 一次都没有断开连接过。两者总体操作上都很流畅。平时我比较习惯于使用 ubuntu,于是在两个主机上都安装了 Ubuntu 12.04_64 的 Server 版本。在安装初始化系统过程中(测试过两次),Ucloud 的速度要快于阿里云主机,粗略估计都是在 20s 以内,因此差别不大。 阿里云主机安装过程中不需要人为参与,选好主机配置即可,主机一旦创建完成,用户名和口令会发送到测试者手机上,而且直接发送的是 root 账户口令。Ucloud 除了选择配置之外,还需要设置强登录密码,使用普通用户登录,感觉更 geek 一点。 默认情况配置下,关闭重启服务器,Ucloud 会发送主机变化短信到手机,阿里云不会。阿里云在系统负载预警方面比较全面,ucloud 侧重于 server 上在线状态和相关服务的预警。 在试用和测试过程中我主要偏向于静态的测试,后面还有一个好玩的 Super PI 测试。 阿里云和 ucloud 都是主机,和实际的服务器使用上没有什么区别。另外阿里云有 paas,需要单独购买,目前支持 php 和 nodejs,一些基本的服务如 memcached 等都可直接使用。 如果做互备,如果我们不使用这两个云平台各自特有的一些服务(主要是阿里云有一些如开放存储服务 OSS 等),相互切换难度上应该是差不多的。 主机概览 项目 阿里云 ucloud 按量付费 支持(不能升级或者调整主机配置*) 不支持 包年包月 支持 支持 操作系统 可重置 可重装 CPU 升级 支持(需要关机) 支持(需要关机) 内存升级 支持(需要关机) 支持(需要关机) 磁盘扩容 支持,可以升级或者添加新的磁盘,最大为 2000G 支持,可以扩容最大到 1000G(与系统盘在同一个主机上),</br/>或者添加新的网络磁盘 udisk 磁盘镜像 支持 支持 带宽升级 支持 支持 其它服务[需要单独购买] 项目 阿里云 ucloud 负载均衡服务 支持(目前免费),需要两台主机以上 支持(目前免费),需要两台主机以上 关系型数据库服务 支持,mysql 和 sqlserver 支持,mysql 和 percona 特有的服务 开放存储服务 OSS、开放数据处理服务 ODPS、开放结构化数据服务 OTS CDN、短信服务(可二次开发)、与又拍、DNSPod 和搜狐 SendCloud 直接绑定 *按量付费不支持更换操作系统;不支持配置变更功能(包括带宽升级、CPU 和内存升级、新增数据盘);“包年包月“和”按量付费“不支持相互更换;1 台云服务器只能选择 1 种,无法同时选择...

August 9, 2013 · 4 min · Le