gitpage Hugo统计每一篇文章浏览量

月盾
接上篇《博客迁移至hugo gitpage》后,因为缺失了每一篇文章的浏览量,而hugo又不具备这样的功能,原因还是gitpage不具备数据存储能力,自然就没办法统计每一篇文章的浏览量了。原本想使用自己服务器提供一个接口来记录,但发现https协议不支持调用http协议的接口,会出现block:mixed-content错误。 错误:https页面去发送http请求报错(浏览器阻止https发送http请求) 问题是明确了,但是我也没办法提供https的接口,免费的证书也用在了www.yuedun.wang上了。 后来想到了leancloud,直接在前端调用api,将数据存储在云端。 <script src="//cdn.jsdelivr.net/npm/leancloud-storage@4.11.1/dist/av-min.js"></script> <script> // https://leancloud.cn/docs/sdk_setup-js.html#hash14962003 // https://leancloud.cn/docs/leanstorage_guide-js.html#hash813593086 const appId = "xxx"; const appKey = "xxx"; const serverURL = "xxx"; AV.init({ appId, appKey, serverURL }); function updateCollect() { const collect = new AV.Query('Collect'); const url = location.pathname; collect.select(['url', 'pv']) collect.equalTo('url', url); collect.first().then((col) => { if (!col) { // 声明 class const Collect = AV.Object.extend('Collect'); // 构建对象 const collect = new Collect(); // 为属性赋值 collect.

博客迁移至hugo gitpage

月盾
为什么迁移? 6月初的时候,3年前买的阿里云服务器到期了,又买了其他服务器,但是只有1年期,于是进行了一番数据,应用迁移,这么一顿操作下来还是挺累的,尤其是在linux上安装mysql,mongodb。 安装后又是连接不上,挺烦的。再想到一年后又是一顿操作,不由得一个激灵。 经过一番的思量后,决定将自建博客迁移至gitpage上。 自建和gitpage优劣对比 首先列出自己博客具备的功能: 首页 包含最近10篇文章的标题和部分内容,最近发表的5篇,分类,标签,友链 目录 所有文章时间线 留言 自维护留言系统 微博 新浪微博,最近出问题不显示了 速记 简单记录 关于 自我介绍 整体比较简单,没什么复杂功能。而很多静态博客也具备这些功能,而且做的更好,所以基本不会有主要功能的缺失。 劣势 在一些细节功能上面确实会有缺失,比如: 评论功能,数据原来是存在自己服务器上的,gitpage不具备数据存储能力,所以需要对接第三方评论或留言功能。 目录缺失,这点主要由博客主题决定,有些主题是没有目录功能的。 PV/UV统计,同样是由于数据存储的缺失,所以gitpage也没有这样的统计功能,但是可以添加谷歌,百度统计之类的。 自定义功能较弱,只能使用主题提供的页面模式,除非不使用静态博客工具,完全自己开发。 不能在线编辑。 优势 免费,没有服务器费用。 可以自定义域名,需要丁点儿的域名费用。 seo良好。 规范的书写格式,是文章内容更统一美观。 更强大的编辑器,可以选择自己喜欢的markdown编辑器。 便于检索。 数据更保险,不易丢失。 整体来说,除了数据存储功能缺失外,其他都是可以实现的。 迁移过程 将mongodb数据中的博客导出为本地markdown文件。 // mongodb数据转markdown function genMd() { return Blog.find({ status: 1 }, null, { sort: { '_id': -1 } }) .then(data => { data.forEach((b) => { debug(b) let tags = b.
vscode正则查找替换

vscode正则查找替换

月盾
查找某一类型字符串: 正则表达式onclick=.*" 会查找到所有: onclick="_msq.push(['trackEvent', '210074305d6b0409-09c7759e04e98528', ''pcpid', '']);" onclick=是固定一样的字符, .代表除\r和\n之外的任意字符,等价于[^\r\n] *代表匹配前面的模式 0或多次 {0,} "这是字符串最后一个字符 在vscode中的效果如下: 至于要替换成什么就看自己需求了,如果要给选中的字符串包裹字符串则需要修改成这样: 查找替换 查找:(onclick=.*") 替换:aaa($1) 结果: 替换字符串两头,保留中间 两部分文字交换位置 相同模式的文字交换位置。 查找:(\(\d{4}-\d{1,2}-\d{2}\)) (\[.*\)) 替换:$2 $1 结果: vscode中一对括号()代表一个变量。 第一组正则 (\(\d{4}-\d{1,2}-\d{2}\)) 对应 $1, 第二组正则 (\[.*\))对应 $2,以此类推。 所以,可以查找多组数据,在替换部分将两个对应变量交换位置即可。

typescript不检查node_moduls

月盾
tsconfig.json 中 exclude node_modules,但 tsc 还是报错。 node_modules/connect-mongo/src/types.d.ts:113:66 - error TS2694: Namespace 'global.Express' has no exported member 'SessionData'. 113 get: (sid: string, callback: (err: any, session: Express.SessionData | null) => void) => void; ~~~~~~~~~~~ node_modules/connect-mongo/src/types.d.ts:114:45 - error TS2694: Namespace 'global.Express' has no exported member 'SessionData'. 114 set: (sid: string, session: Express.SessionData, callback?: (err: any) => void) => void; ~~~~~~~~~~~ node_modules/connect-mongo/src/types.d.ts:118:47 - error TS2694: Namespace 'global.Express' has no exported member 'SessionData'. 118 touch: (sid: string, session: Express.
朱雀发布系统支持scp(rsync)发布

朱雀发布系统支持scp(rsync)发布

月盾
去年花了三天时间开发了一个简易版的nodejs发布系统,它是基于pm2自带的deploy机制开发的,主要原理就是在两台装有pm2的机器直接通信,并执行相应的命令。再往简单了说就是在发布机上远程执行命令,而朱雀发布系统提供了一个图形界面而已。 当时把这个系统定位为nodejs专用发布系统,因为它依赖了pm2,而pm2则是nodejs专用的进程管理工具,其他语言用不到。这个系统的上线也算是解决了我司一直以来没有合适的nodejs发布系统的空缺。 经过9个月的使用,也算比较稳定。但是也存在问题,最大的问题是部署应用方面比较繁琐。 基本流程如下: 发布机和应用服务器设置ssh通信配置。 应用服务器安装git(有自带,但是版本太旧)。 配置git用户名,邮箱。 生成ssh公钥。 把应用服务器的公钥配置到git代码服务器上。以便能拉代码。 发布机远程执行git pull来代码操作,各应用服务把代码拉取下来。 执行编译打包操作。 执行重启服务操作。 部署一次系统还是比较麻烦的,如果应用服务器有多台,可能还要重复这样的操作多次,实在比较麻烦。 使用scp同步代码的方式会比较简单一些,但是像nodejs这样的项目,node_module占了很大比重,如果每次都打包的话会拖慢同步速度,而scp又不具备排除文件夹的能力。 最后找到了rsync命令可以满足需求。然后就是基于rsync实现了一版。不用再依赖pm2,应用服务器也不用强制使用git了。 朱雀和Jenkins对比如何? 要说Jenkins那绝对是持续集成领域的老大哥,自然是功能强大。但是每个团队和产品有其特殊性,Jenkins并不完全适用。而朱雀也有其优势。 朱雀本身部署简单,使用go开发,不依赖运行时,无需安装,开箱即用。 目前支持和测试过的数据库有sqlite3(目前用的,不需要繁琐的安装过程)和mysql。 配置简单。 部署发布一键完成,不需要单独的部署过程。 并行发布。 审批,通知,权限。 开源,可定制开发。 项目地址:朱雀发布系统
一体LED可伸缩变焦手电筒拆解

一体LED可伸缩变焦手电筒拆解

月盾
先看看一体LED可伸缩变焦手电筒长什么样子 这种手电筒刚买回来几个月就不亮了,以为没电了,充电了也不行,想拆开看看却发现无从下手,手电筒是一体的,并没有地方可扭开。 按钮部位看起来是可拆解的,想要转动一下,发现无法转动,最后抱着死马当活马医的心态,大不了拆坏了,随便用工具撬了下尾部凹槽部分,发现有活动迹象,然后就继续撬,果然是大力出奇迹。最后就是下面图展示的样子,有明显损坏痕迹,不过也没办法,实在不好拆。拆开后发现电池线断了,将就着接上后就好了。 最后,虽然不建议买这种手电筒,但是既然您看到本文了,那也就有救了。 祝大家五一快乐!

easy-monitor qps监控

月盾
Easy-Monitor是一款轻量级的Node性能监控工具,仅仅需要项目入口 require 一次,就可以非常便捷地展示出进程的状态细节。 Easy-Monitor主要提供以下的功能: 找出执行时长耗费最久的5个或者更多的函数 找出那些执行时间超出预期的函数 找出v8引擎无法优化的函数 Easy-Monitor的特点: 轻量级:非传统C/S物理分离模式,require 后即可使用,没有额外的监控server/agent部署成本。 运行时:针对的是运行时的函数性能以及内存细节进行处理展示,可用于线上生产环境项目。 无状态:永远展示的是开发者访问时的业务进程状态 关于监控qps,作者在文档中并没有提到qps这样的关键字,很多人也不知道怎么监控qps。 不过在监控界面中有这样的指标数据: 所以我从源码入手,找到了该数据指标的源头是这样的: const data = { osCpu: Number((used_cpu * 100).toFixed(2)), osMem: Number((used_memory_percent * 100).toFixed(2)), maxDisk: max_disk_usage, disks: disks_json, load1: Number(load1.toFixed(2)), load5: Number(load5.toFixed(2)), load15: Number(load15.toFixed(2)), nodeCount: node_count, scavengeTotal: total_scavange_duration, scavengeAverage: scavange_duration_last_record, marksweepTotal: total_marksweep_duration, marksweepAverage: marksweep_duration_last_record, qps: Number((http_response_sent / 60).toFixed(2)), rtExpired: http_patch_timeout, rtAverage: http_rt, }; 这是接口返回的数据,包含了qps数据,那么qps实际上就是http_response_sent,所以监控中就可以这样设置qps了: @http_response_sent/60 > 10

使用sveltekit开发一个服务端渲染(SSR)项目

月盾
上篇简单介绍了sapper和sveltekit的发展,目前sveltekit还只是Beta版本,有很多不确定因素存在,有可能会有大的变更,所以还不推荐在生产环境中使用,不过在个人项目和小项目中可以大胆尝试。 今天我们就正式使用sveltekit开发一个web项目。 第一步:创建项目 mkdir my-app cd my-app npm init svelte@next npm install npm run dev 这样就可以创建一个简单的项目了,不过和我们真实需求还有些差距,既然是使用sveltekit,那么最重要的原因是其支持服务端渲染了。这就需要从服务端获取数据,接下来就实现这样的需求。 第二步:路由 和sapper一样,sveltekit也是基于文件系统的的路由器,这就需要我们来合理的组织目录结构。路由的核心目录是src/routes,当然,这个也是可配置的,按照自己的需求修改svelte.config.cjs,参考文档:https://kit.svelte.dev/docs#configuration。 我们以一个博客系统为例,在scr/routes下创建blog目录,光有目录还不行,如果想要访问 /blog 路由,还需要创建index.svelte文件,内容如下: <script context="module"> /** * @type {import('@sveltejs/kit').Load} */ export async function load({ page, fetch, session, context }) { return fetch(`blog.json`)// index.json.js = blog.json或blog/blog.json .then((r) => r.json()) .then((posts) => { console.log(posts); return { props: { posts } }; }); } </script> <script> export let posts; </script> <svelte:head> <title>Blog</title> </svelte:head> <h1>Recent posts</h1> <ul> {#each posts as post} <!

关于svelte框架——sapper和sveltekit的发展

月盾
虽然您可能现在还没有听说过svelte,但是其实svelte的发展速度超过了你的想象。 本文主要讲的是关于sapper和sveltekit这两款框架的发展。 svelte作者里奇·哈里斯(Rich Harris)在2020年10月的svelte峰会上表示:sapper永远不会发布1.0版本。 也就是说sapper不会发布正式版,一直处于非稳定版本。也可能放弃更新。 主要原因是sapper多年来代码库变得凌乱,但更主要的原因是最近网络发生了很大变化。 而作者放弃sapper后的另一种选择是开发SvelteKit。 Sapper和SvelteKit都是svelte的开发框架,类似于vue的nuxt框架。 sveltekit包含的功能有: 服务端渲染(SSR) 路由 typescript支持 less, scss支持 serverless vite打包 可以看到,sveltekit几乎包含了所有我们想要的功能,既能高效开发,又有高性能。 创建sveltekit的方法: mkdir my-app cd my-app npm init svelte@next npm install npm run dev 需要注意,您的nodejs版本需要更新到v12以上,否则可能出现以下错误: $ npm run dev -- --open > sveltekit-app@0.0.1 dev D:\workspace\sveltekit-app > svelte-kit dev "--open" D:\workspace\sveltekit-app\node_modules\@sveltejs\kit\svelte-kit.js:2 import './dist/cli.js'; SyntaxError: Unexpected string at Module._compile (internal/modules/cjs/loader.js:723:23) at Object.Module._extensions..js (internal/modules/cjs/loader.

/bin/rm: argument list too long

月盾
有人在服务器上不小心执行了rm -fr /*,而我想在删除某个文件夹下面的文件却遇到/bin/rm: argument list too long。 意思是我删除的文件太多了,这倒有点稀奇。 那怎么才能删除呢? 试着直接删除目录也不行,这问题能难倒我,但难不倒百度。 使用ls | xargs -n 1000 rm -fr ls删除,可是一直在输出错误提示: rm: invalid option -- 's' Try 'rm --help' for more information. 出现这个情况的原因是文件名是这种类型:-abc.txt。就是前面带了-。 删除方式是: rm -- -foo 或 rm ./-foo 只看见报错,到底有没有在删文件?想要知道,那么把删除命令改成这样 ls | xargs -n 1000 rm -frv ls rm命令加个参数v,用来显示删除信息。 最终会输出这样的提示信息, removed ‘zMJ1MgKdzgbjNsWawUcX7OO3WspyxZEU.json’ 为了让它在后台执行可以这样: ls | xargs -n 1000 rm -frv ls &