[技术/05月 19, 2016]

每天和烂代码打交道,有时候也会觉得奇怪,不过今天也是碰到了一些不一样的情况。今天在整理代码的是否出现了一个文件中两种不同的方式声明一个方法的案例,如下:

var test=function(){
    console.log('test var')
}

function test(){
    console.log('test function')
}

在这个script中出现了两个这个方法的声明,平常我肯定会说两种方法声明都是一样的,但是上面这个例子打破了我的认知,后来想想也是对的。就是上面这个例子,最后调用test方法的时候,打印的是test var。具体解释其实也简单,js引擎解析js代码的时候会先把方法这些解析到当前作用域中,然后再执行代码,所以虽然var在上面,但是var是后执行的,在后面再覆盖的test方法,所以导致了这个问题。

具体可以如下这个文章中也有提及 http://www.jianshu.com/p/7caabf3d6a5a

2.预编译&执行
当JavaScript引擎解析脚本时,它会在预编译期对所有声明的变量和函数进行处理。

在执行前会进行类似“预编译”的操作:首先会创建一个当前执行环境下的活动对象,并将那些用var申明的变量设置为活动对象的属性,但是此时这些变量的赋值都是undefined,并将那些以function定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义。
在解释执行阶段,遇到变量需要解析时,会首先从当前执行环境的活动对象中查找,如果没有找到而且该执行环境的拥有者有prototype属性时则会从prototype链中查找,否则将会按照作用域链查找。遇到var a = …这样的语句时会给相应的变量进行赋值(注意:变量的赋值是在解释执行阶段完成的,如果在这之前使用变量,它的值会是undefined)

crontab设置的时候总是会发现不执行或者执行出错的问题,一般有这么一些情况:

  1. crontab和用户的权限不一样,环境变量不一样
  2. crontab的命令没有使用绝对路径,使用的相对路径

一般上面的问题可以通过对cmd运行的过程中加入log,然后来检查log可以发现,但是我今天遇到了一个特例的情况,比较隐蔽,这里分享给大家。

具体情况如下:

我需要在服务器上面每天早上8点半发送一个数据统计的日报,然后设置为如下的

30 08 * * * /bin/bash /srv/xxxxx.sh

最后的结果是早上8点半的时候没有运行,具体是否有运行可以查看如下的log

/var/log/cron

然后想到是否是因为其他原因,就把时间调整为如下,让它08点每个时间运行,发现还是不行

* 08 * * * /bin/bash /srv/xxxxx.sh

最后无奈调整为如下的格式,每分钟一次

* * * * * /bin/bash /srv/xxxxx.sh

最后发现程序运行了,然后想来想去是否是时间不一致,后面想起来发现服务器开起来之后就没有重启过,但是中间我们修改过时区,很可能是因为crond启动的时区与后面修改的时区不一致,所以导致crond对于时间的判断也不对了,所以重启crond就ok了

service crond restart
[生活/01月 1, 2016]

2015总结

因为没有过节的习惯,所以等到最后一天了,才发现需要对过去的一年总结总结了。依然是2016年第一天才开始写2015年的总结。

看着2014年的总结写2015年的总结看起来有一些悲伤。2015年的计划是:

  1. 开始有计划的锻炼身体,健康比较重要
  2. 技术上可能需要更加往架构和团队方向走
  3. 旅游这种事情可以继续来一点
  4. 管理方面需要多多加强,希望能带团队做出更好的成绩
  5. 治疗拖延症

这里说一下完成的情况:

  1. 大概是9-10月份的时候开始跑步,也是工作压力不大,然后坚持了两个月,效果是跑步起来不怎么喘气了,体重减了快十公斤,肚子小了好多,可以轻松跑个十公里。现在因为天冷和工作忙把日常跑步给去掉了,但是目前培养成了运动的一些习惯和潜意识,希望多多保持。
  2. 技术上面今年开始是往管理和团队方向走。比如说团队管理,今年公司架构转变为跟业务走之后,实际上我的工作变得不多。因为业务工作比较多,同时大家有固定的版本发布计划,所以技术上的一些事情也不大好推进。所以我越来越觉得我的一些工作看起来是比较虚的。这也是之后离职的一个原因。后来想明白了,就是在团队还没大到一定程度的时候,我觉得下面团队成员能力的提高应该把他放到比较重要的位置。
  3. 旅游好像就和公司去过巴厘岛,其他没有计划,可能也是因为年初不久就分手,一个人不大想去旅游导致的吧。
  4. 管理方面协助公司把组织架构调整为以业务为导向,同时让整个团队(产品+业务)的流程用禅道等系统管理起来,把办法发布设置为3个礼拜一个周期,协助建立起测试团队。总的来说还是有一些进步,不过执行能力方面还需要加强。
  5. 拖延症的问题,我后来想了想有时候不是我故意拖延,有时候是有一些东西是我内心不想做的。我觉得拖延症问题在2015算是有一些改善的,自己会主动地去找自己身上存在的问题,并且自己主动会去改变一些自己不满的现状。

除了计划内的事情,还有一些计划外的事情发生,总的来说波澜不惊,自己也是有过比较周到的考虑:

  1. 和前女友分手,总体来说有点无奈,做的有点不好的是没有和对方家长沟通好。
  2. 快年底的时候丢掉奖金,丢掉期权,丢掉那边一个十几个下属的管理位置换了一个新的创业公司,没有后悔,希望能在新的一年能帮助新公司越做越好。
  3. 炒股从盈利10w到亏2w再到最后盈利2w的一段过山车的历程,好在结果还算可以接受,技术方面长进不多,心态倒是长进了一些。
  4. 比特币把之前在里面亏的1w多又赚回来了,有时候总是觉得幸福来的太突然。

2016的展望

  1. 找个能陪伴终生的人,虽然比较难,但是希望能够继续。
  2. 帮助新公司在业务上面达到新的突破,同时在技术管理上面多加成长,主要是在培养新人方面。
  3. 学习一门新的语言开发,多实践一下新的潮流技术,在后台架构上面希望也有所长进。
  4. 多认识一些各行各业的朋友,多与人交流。
  5. 保持好锻炼身体的习惯。
  6. 跑一次全程马拉松。
  7. 国内国外各一次旅游。

最近为公司的前端搭建了一套js报错统计功能,使用的架构很简单,就是前端使用window.onerror函数捕获错误,然后上传到自己的一个log接口,log接口获取一些额外的信息就直接http请求上报给ElasticSearch服务了。

话说上报给ElasticSearch的接口真是超级简单,如果为了保证ElasticSearch挂掉的时候,数据也是不丢失的,我们可以在log接口与ElasticSearch之间加一个message queue,当然目前还没加上。

然后遇到了ElasticSearch的一个坑,那就是aws的ElasticSearch服务默认是提供一个kibana服务的,但是问题是老版本的kibana自带的服务器是一个jettey服务器,然后里面一个js文件是一个超级大的js,大概有5m。最坑的是jettey服务器没有把js做gzip压缩,而且没有设置http的缓存的头,导致每次打开那个kibana都下载那个js不下来,同事的可以下载下来,但是需要好久,几近崩溃。

因为aws的ElasticSearch服务器是不提供ssh登录的,不然我们加上一个nginx应该也是可以的。没有办法的情况下咨询aws的支持人员,大概16小时之后他们回复了一下,说默认服务器是没开这个,后面在新版本修复这个bug,但是aws不能提供给我们办法,最后给我们的办法是我们自己搭建kibana,然后把kibana配置里面的ElasticSearch地址指向那个aws的ElasticSearch集群即可。

果断的三下五除二把自己的kibana安装了之后,在服务器上面加上一个nginx配置,然后配置了一下gzip和缓存头,问题没有了,可以愉快地玩耍了。

但是现在我们的ElasticSearch都是直接暴露在外网可以访问的,然后kibana也是直接的访问,没有任何的权限控制。所以我想当然地把kibana的nginx配置里面加上了一个basic auth验证。加上之后问题来了,貌似请求elastic-search出错。最后试了一下kibana自己的配置文件配置basic auth也不行。错误如下:

Kibana: Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header.

搜索了一下发现好像是aws的http请求需要有一个权限的认证,可以参考这里。然后表现就是我去掉basic authentication就好了。开始想到的处理方法是在nginx里面去掉basic authentication的http头,最后发现nginx做不了这件事情。

最后在kibana4.0.1的源代码里面去看,发现原来新的kibana是使用的nodejs开发的服务器,服务器请求ElasticSearch的时候是使用的nodejs去代理的,一直找到kibana/src/routes/proxy.js 里面找到代理请求的那个地方,然后发现它是直接从原来的请求里面拿过俩头,然后放到新的请求里面去,中间也有对一些头做了一些处理,我就在这个地方把Authenticaton的http-头部去掉,然后系统果然又好了。

最后为了安全,我把aws的ElasticSearch访问控制限制到了只能ip访问,把我们的两个服务器ip设置进去之后,过了大概十多分钟的时间,访问控制生效了,使用如下命令:

curl -XGET https://<xxxxxx>.ap-southeast-1.es.amazonaws.com/

错误出现为:

{"Message":"User: anonymous is not authorized to perform: es:ESHttpGet on resource: arn:aws:es:ap-southeast-1:227729285155:domain/log-es-cluster/"}%

从配置了ip可以访问的服务器上面去请求的时候,返回如下:

{
  "status" : 200,
  "name" : "Paibo",
  "cluster_name" : "227729285155:log-es-cluster",
  "version" : {
    "number" : "1.5.2",
    "build_hash" : "62ff9868b4c8a0c45860bebb259e21980778ab1c",
    "build_timestamp" : "2015-04-27T09:21:06Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.4"
  },
  "tagline" : "You Know, for Search"
}

说明配置成功了。总体的简单的权限控制就OK了。

最近在做微信的js-sdk开发,觉得最麻烦的莫过于调试了。因为微信的支付接口步骤多,后台也是第一次接入,所以调试的事情就比较麻烦了。Android手机和iOS在开发的情况下是可以直接调试webview的,但是如果你是需要在微信的第三方里面去调试你的webview的表现呢。现在还不知道微信是否有接口可以打开它的开发模式,不过我总算只找到了一些简单的方法来解决调试的问题了。其实方法很简单:

  1. 自己封装log接口,当然也可以error接口。自己封装的好处就是在一个总的入口处可以去加一些逻辑的时候很方便。比如我经常会封装获取json请求的接口,因为这里加逻辑的情况很多,log的接口处理也会比较多。

  2. 如果url带了一个loghost的参数,就有log的时候,就把log发送到 http:///log的接口,这个接口就可以后台看到log信息了

  3. 上面解决了log的问题,还有如果js报错怎么办,这个时候我们就要请出window.onerror函数了,在这个函数回调里可以把报错的js也上报到log接口就好了,只需要打log的时候区分一下就好。

  4. 这样只解决了从webview给我们的服务器发送log的情况,如果我们想调用webview里面的js代码怎么办呢?可能很多人就会有想法了,websocket长连接,这是一个办法,不过因为我们主要是用来调试,性能要求没这么高,所以我们只需要用nodejs这种长连接服务器,hold住连接不施放就OK了,然后客户端50秒左右发起一次请求。这样客户端就可以接收服务器端的console连接了。

  5. 不过有一个问题需要解决,就是多个页面的问题,多个页面连上来就有多个连接了,所以就需要分配id什么的,想来想去这个问题好像基本上是一个伪命题,你自己用一台服务器调试一个网页好像就OK了..

说到这里应该大部分比较清楚了..

»