月盾的博客

go并发获取数据

月盾
go语言可以很轻松的实现并发获取数据,就算是新手也可以按部就班的套用现成的并发模式来实现并发。以下是一个简单的测试程序,其中有串行,并行。 package main import ( "sync" "time" "fmt" ) func main() { syncFunc() fmt.Println(">>>>>>>>>>>>>>>") asyncFunc() fmt.Println(">>>>>>>>>>>>>>>") asyncChanFunc() } // 串行执行 func syncFunc() { var n,m,x int start := time.Now() fmt.Println("syncFunc start:",start) func () { time.Sleep(time.Second*1) n = 1 }() func () { time.Sleep(time.Second*2) m = 2 }() func () { time.Sleep(time.Second*3) x =3 }() t := time.Now() fmt.Println(t) elapsed := t.Sub(start) fmt.Println("syncFunc end:", elapsed, n, m, x) } // 并行执行 func asyncFunc() { var n,m,x int var wg sync.

go测试函数的编写及运行

月盾
go test命令是一个按照一定的约定和组织的测试代码的驱动程序。在包目录内,所有以_test.go为后缀名的源文件并不是go build构建包的一部分,它们是go test测试的一部分。 在\*_test.go文件中,有三种类型的函数:测试函数、基准测试函数、示例函数。一个测试函数是以Test为函数名前缀的函数,用于测试程序的一些逻辑行为是否正确; go test命令会调用这些测试函数并报告测试结果是PASS或FAIL。基准测试函数是以Benchmark为函数名前缀的函数,它们用于衡量一些函数的性能;go test命令会多次运行基准函数以计算一个平均的执行时间。示例函数是以Example为函数名前缀的函数,提供一个由编译器保证正确性的示例文档。 测试函数 每个测试函数必须导入testing包。测试函数有如下的签名: func TestName(t *testing.T) { // ... } 测试函数的名字必须以Test开头,可选的后缀名必须以大写字母开头: func TestSin(t *testing.T) { /* ... */ } func TestCos(t *testing.T) { /* ... */ } func TestLog(t *testing.T) { /* ... */ } 其中t参数用于报告测试失败和附加的日志信息。让我们定义一个实例包gopl.io/ch11/word1,其中只有一个函数IsPalindrome用于检查一个字符串是否从前向后和从后向前读都是一样的。(下面这个实现对于一个字符串是否是回文字符串前后重复测试了两次;我们稍后会再讨论这个问题。) // gopl.io/ch11/word1 // Package word provides utilities for word games. package word // IsPalindrome reports whether s reads the same forward and backward. // (Our first attempt.) func IsPalindrome(s string) bool { for i := range s { if s[i] !

Golang- import 导入包的语法

月盾
一、 包的导入语法 在写Go代码的时候经常用到import这个命令用来导入包文件,看到的方式参考如下: import( "fmt" ) 然后在代码里面可以通过如下的方式调用 fmt.Println("hello world") 上面这个fmt是Go语言的标准库,他其实是去GOROOT下去加载该模块,当然Go的import还支持如下两种方式来加载自己写的模块: 相对路径 import "./model" //当前文件同一目录的model目录,但是不建议这种方式import` 绝对路径 import "shorturl/model" //加载GOPATH/src/shorturl/model模块` 上面展示了一些import常用的几种方式,但是还有一些特殊的import,让很多新手很费解,下面是三种导入包的使用方法。 点操作 有时候会看到如下的方式导入包 import( . "fmt" ) 这个点操作的含义就是这个包导入之后在你调用这个包的函数时,你可以省略前缀的包名,也就是前面你调用的 fmt.Println("hello world") 可以省略的写成 Println("hello world") 别名操作 别名操作顾名思义可以把包命名成另一个用起来容易记忆的名字 import( f "fmt" ) 别名操作调用包函数时前缀变成了重命名的前缀,即 f.Println("hello world") _操作 这个操作经常是让很多人费解的一个操作符,请看下面这个import import ( "database/sql" _ "github.com/ziutek/mymysql/godrv" ) _操作其实只是引入该包。当导入一个包时,它所有的init()函数就会被执行,但有些时候并非真的需要使用这些包,仅仅是希望它的init()函数被执行而已。这个时候就可以使用_操作引用该包了。即使用_操作引用包是无法通过包名来调用包中的导出函数,而是只是为了简单的调用其init函数()。 二、 包的导入过程说明 程序的初始化和执行都起始于main包。如果main包还导入了其它的包,那么就会在编译时将它们依次导入。有时一个包会被多个包同时导入,那么它只会被导入一次(例如很多包可能都会用到fmt包,但它只会被导入一次,因为没有必要导入多次)。当一个包被导入时,如果该包还导入了其它的包,那么会先将其它包导入进来,然后再对这些包中的包级常量和变量进行初始化,接着执行init函数(如果有的话),依次类推。等所有被导入的包都加载完毕了,就会开始对main包中的包级常量和变量进行初始化,然后执行main包中的init函数(如果存在的话),最后执行main函数。下图详细地解释了整个执行过程: 通过上面的介绍我们了解了import的时候其实是执行了该包里面的init函数,初始化了里面的变量,_操作只是说该包引入了,只初始化里面的init函数和一些变量,不能通过包名来调用其它的函数,这有什么用呢?往往这些init函数里面是注册自己包里面的引擎,让外部可以方便的使用,就很多实现database/sql的引起,在init函数里面都是调用了sql.Register(name string, driver driver.Driver)注册自己,然后外部就可以使用了。 原文地址:http://blog.csdn.net/zhangzhebjut/article/details/25564457

github提交不记录Contributions

月盾
github上提交了很多commit但是没有Contributions绿色方块,原因是提交的email和github不匹配,使用git log查看记录中使用的邮箱是否是github的邮箱,如果不是也不需要做什么修改,只需要在github上添加对应的邮箱地址即可。 右上角头像-settings-emails-Add email address 验证邮箱后就会立马重新统计

pm2设置NODE_ENV环境变量

月盾
nodejs中经常使用到环境变量,最常见的如:process.env.NODE_ENV。那么在生产环境中使用pm2如何设置环境变量? 设置方式一:shell命令设置 linux:export NODE_ENV=development&& node app.js win:set NODE_ENV=development&& node app.js 一般是作临时变量在系统启动时设置,不影响其他系统,也可同时运行开发环境和生产环境,只需要根据process.env.NODE_ENV来运行不同逻辑即可。 设置方式二:配置文件设置 要在pm2设置环境变量也很简单。 pm2 start pm2.json –env production --env production参数是为了设置环境变量,由pm2.json中的配置决定设置什么样的环境变量。 pm2.json { "apps" : [{ "name": "issue", "cwd": "dest", "script" : "bin/www.js", "instances" : "2", "exec_mode" : "cluster", "env": { "NODE_ENV": "development", "PORT": 3002 }, "env_production" : { "NODE_ENV": "production", "PORT": 3003 }, "log_date_format": "YYYY-MM-DD_HH:mm Z", "merge_logs": true }] } 如果不加参数则默认使用 "env": { "NODE_ENV": "development", "PORT": 3002 } 结果:NODE_ENV=development,PORT=3002 加--env production则使用的是

webpack构建vue项目警告

月盾
bundle.js:935 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build. (found in <Root>) 解决方案:与entry属性平级添加 resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js' //该路径为node_modules下的vue目录 } } // 需要编译器 new Vue({ template: '<div>{{ hi }}</div>' }) // 不需要编译器 new Vue({ render (h) { return h('div', this.hi) } }) 出现警告的原因是使用了template属性。 文文点到为止,详情请直接访问中文官方文档https://cn.vuejs.org/v2/guide/installation.html#对不同构建版本的解释

再聊docker和nodejs

月盾
上一篇写到了如何在docker中运行nodejs,运行方式是在docker中安装了pm2来保证node服务宕机重启,这种方式更像是把docker当做虚拟机来使用。其实,既然使用了docker的话就可以不使用pm2来管理进程,因为docker自身可以充当守护进程,在node进程退出时进行重启。只要在启动docker容器时加上–restart=always参数即可。例如:docker run -d --restart=always -p 3000:3000 mynode:1 没有pm2如何开启多进程 使用pm2可以开启多node进程,并且自带负载均衡,但是有个限制,pm2可以开启的进程数是CPU最大核心数。而使用docker的话就不会受限于此了,开启几十个上百个node服务都可以,然后通过nginx实现负载均衡。不过要手动开启几十上百个docker容器那怎么行?让我手动开启3个都很烦了,这时候就需要用到docker编排工具了,比如:Docker Swarm、Kubernetes、docker compose等,可以一键开启多个容器。但是使用编排工具启动docker端口就不确定了,是由编排工具随机开启服务端口的,这又要做到服务注册发现,所以这些工具结合起来使用。 哪一种部署方式支持并发高? 使用jmeter在本机上进行了简单的并发测试,服务端进行简单的10万次hash计算,使用pm2开启4个实例,docker开启5个实例。docker使用Nginx做负载均衡,单次访问响应时间在1.2s~1.4s之间不等,在200个并发的情况下,两种模式响应时间相差不大,docker模式响应时间略占优势,大概快了0.1s。当并发数在300以上时两者的响应时间都有增加,此时docker部署方式出现了响应失败的情况,pm2就比较稳定了,虽然响应时间增加,但是并未出现过响应失败。 所以在单机上低并发docker还是有点优势,如果在高并发情况下还是pm2更稳定一些。(以上测试是单机上进行,准确性并不高)

pm2日志记录和日志分割

月盾
pm2介绍 pm2是nodejs进程管理工具,现在基本是node生产服务器的标准选择,可以帮助我们实现node多进程服务,开启的多个实例自动实现负载均衡。 最重要的是保证node单进程不会因为错误退出,作为守护进程保证nodejs服务不宕机。 总体来说就是有性能监控、自动重启、负载均衡的作用。 pm2-logrotate介绍 pm2本身是可以输出日志文件的,默认的文件路径: error log path │ /home/username/.pm2/logs/app-error-0.log out log path │ /home/username/.pm2/logs/app-out-0.log 但是pm2的日志文件不能自动分割,这会导致一个文件不断变大,不但影响性能,查看这些日志也会带来麻烦。所以需要pm2-logrotate来实现自动分割日志。 安装pm2-logrotate pm2 install pm2-logrotate,是用pm2命令,不是npm命令 pm2-logrotate配置 max_size (默认 10M): 最大为多少时进行分割,例如: 10G, 10M, 10K retain (Defaults to all): This number is the number of rotated logs that are keep at any one time, it means that if you have retain = 7 you will have at most 7 rotated logs and your current one. compress (默认 false): 是否压缩日志 dateFormat (默认 YYYY-MM-DD_HH-mm-ss) : 日志格式 rotateModule (Defaults to true) : Rotate the log of pm2’s module like other apps workerInterval (Defaults to 30 in secs) : You can control at which interval the worker is checking the log’s size (minimum is 1) rotateInterval (Defaults to 0 0 * * * everyday at midnight): This cron is used to a force rotate when executed.

最新版火狐Firefox Quantum 57没有pocket按钮

月盾
从火狐量子浏览器开始,pocket按钮集成到了地址栏右侧, 如果你找不到,那么有可能是在浏览器配置中关闭了,开启方式: 地址栏中输入about:config,点击“我了解风险”继续,搜索“pocket.enabled”,如果是false双击修改为true就会出现。 其他情况可参考:https://help.getpocket.com/article/942-where-is-the-pocket-button-in-firefox

在docker中运行nodejs

月盾
首先看项目目录: 再看Dockerfile文件内容: # 以最新的node为基础镜像 FROM hub.c.163.com/library/node:latest # 工作目录为app WORKDIR /app # 拷贝当前所在项目根目录到app目录 COPY . /app # 全局安装pm2 RUN npm install pm2 -g EXPOSE 8081 #使用pm2启动nodejs,如果没有--no-daemon参数docker启动后就退出 CMD ["pm2-runtime", "dest/server.js", "--no-daemon"] # ENTRYPOINT ["node", "server.js"] 或者在Dockerfile中不添加CMD命令,可以在启动docker时执行命令: docker run --name ks -ti -p 8081:8081 kser:pm2 pm2-runtime dest/server.js 如果是后台运行的docker: docker run --name ks -d -p 8081:8081 kser:pm2 pm2-runtime dest/server.js -d选项是后台运行 需要进入到docker查看pm2运行情况 ,可以通过docker exec -ti ks /bin/sh查看运行的容器内部情况 要不要在docker中使用pm2运行nodejs pm2可以监控nodejs进程,如果进程挂了,可以自动重启 pm2可以设置启动的nodejs进程个数,提高服务性能 pm2可以设置日志记录 pm2可以设置端口,避免端口冲突 docker已经提供了自动重启的功能,可以这样启动nodejs服务: docker run --name ks -d --restart=always -p 8081:8081 kser:pm2 pm2-runtime dest/server.