shell判断一个进程是否存在,如果不存在重启该进程

2017年6月12日 由 Creater 没有评论 »

Linux下shell脚本编程实例
判断一个进程是否存在,如果不存在重启该进程:

#!/bin/bash
while [ 1 ]
do
    SendMail_is_exstit=$(ps -ef | grep "feed SendMail" | grep -v grep | wc -l)
    if [ ${SendMail_is_exstit} == 0 ]
    then
        cd /var/www/sdkfeed/
                #要执行的脚本命令,我这里是跑redis队列发送邮件脚本
        ./app/Console/cake SendMail
                  
    fi
    sleep 60
done

用SNMP实现对大型网络的轻松管理

2017年6月1日 由 Creater 没有评论 »

一、原理介绍:

SNMP简介
  目前网络中用得最广泛的网络管理协议是SNMP(Simple Network Management Protocol,简单网络管理协议)。SNMP是被广泛接受并投入使用的工业标准用于保证管理信息在网络中任意两点间传送,便于网络管理员在网络上的任何节点检索信息、修改信息、定位故障、完成故障诊断、进行容量规划和生成报告
SNMP采用轮询机制,只提供最基本的功能集,特别适合在小型、快速和低价格的环境中使用。SNMP的实现基于无连接的传输层协议UDP,因此可以实现和众多产品的无障碍连接

SNMP的工作机制
SNMP分为NMS和Agent两部分:
NMS(Network Management Station,网络管理站)是运行客户端程序的工作站,目前常用的网管平台有QuidView、Sun NetManager和IBM NetView。
Agent运行在网络设备上的服务器端软件
NMS可以向Agent发出GetRequest、GetNextRequest和SetRequest报文,Agent接收到NMS的这些请求报文后,根据报文类型进行Read或Write操作,生成Response报文,并将报文返回给NMS。
Agent在设备发生异常情况或状态改变时(如设备重新启动),也会主动向NMS发送Trap报文,向NMS汇报所发生的事件。

SNMP的版本
目前,设备中的SNMP Agent支持SNMP v3版本,兼容SNMP v1版本、SNMP v2C版本
SNMP v3采用用户名和密码认证方式。
SNMP v1、SNMP v2C采用团体名(Community Name)认证,非设备认可团体名的SNMP报文将被丢弃。SNMP团体名用来定义SNMP NMS和SNMP Agent的关系。团体名起到了类似于密码的作用,可以限制SNMP NMS访问设备上的SNMP Agent。用户可以选择指定以下一个或者多个与团体名相关的特性:
1.定义团体名可以访问的MIB视图。

2.设置团体名对MIB对象的访问权限为读写权限(write)或者只读权限(read)。具有只读权限的团体名只能对设备信息进行查询,而具有读写权限的团体名还可以对设备进行配置。
3.设置团体名指定的基本访问控制列表。

设备支持的MIB
在SNMP报文中用管理变量来描述设备中的管理对象。为了唯一标识设备中的管理对象,SNMP用层次结构命名方案来识别管理对象。整个层次结构就像一棵树,树的节点表示管理对象,如下图1-1所示。每一个节点,都可以用从根开始的一条路径唯一地标识。

5635432_13471846351gH3

MIB(Management Information Base,管理信息库)的作用就是用来描述树的层次结构,它是所监控网络设备的标准变量定义的集合。在图1-1中,管理对象B可以用一串数字{1.2.1.1}唯一确定,这串数字是管理对象的对象标识符(Object Identifier)。
系统支持的常见MIB如下表1-1所示。


5635432_1347184638OVT9

单个项目配置composer

2017年5月22日 由 Creater 没有评论 »

1.进入到项目根目录执行:

composer config repo.packagist composer https://packagist.phpcomposer.com
执行完查看composer.json后面自动新增了一段代码:

“repositories”: {
“packagist”: {
“type”: “composer”,
“url”: “https://packagist.phpcomposer.com”
}
}
2.也可以直接在composer.json文件后面新增上面的代码就ok了

正确的 Composer 扩展包安装方法

2017年5月22日 由 Creater 没有评论 »

问题说明

我们经常要往现有的项目中添加扩展包,有时候因为文档的错误引导,如下图来自 这个文档 的:

file

composer update 这个命令在我们现在的逻辑中,可能会对项目造成巨大伤害。

因为 composer update 的逻辑是按照 composer.json 指定的扩展包版本规则,把所有扩展包更新到最新版本,注意,是 所有扩展包,举个例子,你在项目一开始的时候使用了 monolog,当时的配置信息是

"monolog/monolog": "1.*"

安装的是 monolog 1.1 版本,而一个多月以后的现在,monolog 已经是 1.2 了,运行命令后直接更新到 1.2,这时项目并没有针对 1.2 进行过测试,项目一下子变得很不稳定,情况有时候会比这个更糟糕,尤其是在一个庞大的项目中,你没有对项目写完整覆盖测试的情况,什么东西坏掉了你都不知道。

那应该使用哪个命令呢?install, update 还是 require ?

接下来我们一一解释。

简单解释

composer install - 如有 composer.lock 文件,直接安装,否则从 composer.json 安装最新扩展包和依赖;
composer update - 从 composer.json 安装最新扩展包和依赖;
composer update vendor/package - 从 composer.json 或者对应包的配置,并更新到最新;
composer require new/package - 添加安装 new/package, 可以指定版本,如: composer require new/package ~2.5.

流程

下来介绍几个日常生产的流程,来方便加深大家的理解。

流程一:新项目流程
创建 composer.json,并添加依赖到的扩展包;
运行 composer install,安装扩展包并生成 composer.lock;
提交 composer.lock 到代码版本控制器中,如:Git;

流程二:项目协作者安装现有项目
克隆项目后,根目录下直接运行 composer install 从 composer.lock 中安装 指定版本 的扩展包以及其依赖;

此流程适用于生产环境代码的部署。

流程三:为项目添加新扩展包

使用 composer require vendor/package 添加扩展包;
提交更新后的 composer.json 和 composer.lock 到代码版本控制器中,如:git;

关于 composer.lock 文件

composer.lock 文件里保存着对每一个代码依赖的版本记录(见下图),提交到版本控制器中,并配合composer install 使用,保证了团队所有协作者开发环境、线上生产环境中运行的代码版本的一致性。

这里写图片描述

关于扩展包的安装方法

那么,准备添加一个扩展包,install, update, require 三个命令都可以用来安装扩展包,选择哪一个才是正确的呢?

答案是:使用 composer require 命令

另外,在手动修改 composer.json 添加扩展包后,composer update new/package 进行指定扩展包更新的方式,也可以正确的安装,不过不建议使用这种方法,因为,一旦你忘记敲定后面的扩展包名,就会进入万劫不复的状态,别给自己留坑呀。

上面的概念不论对新手或者老手来说,都比较混淆,主要记住这个概念:

原有项目新添加扩展的,都使用 composer require new/package 这种方式来安装。

需要加版本的话

composer require "foo/bar:1.0.0"

更新指定扩展到指定版本

有时候你之前使用过的扩展包,加入了新功能,你想更新单独这个扩展包到指定版本,也可以使用 require 来操作。

如下面例子,需要更新 “sami/sami”: “3.0.” 到 “sami/sami”: “3.2.”
这里写图片描述

命令行运行:
这里写图片描述

挖掘微信Web版通信的全过程

2017年5月22日 由 Creater 没有评论 »

1.微信服务器返回一个会话ID

微信Web版本不使用用户名和密码登录,而是采用二维码登录,所以服务器需要首先分配一个唯一的会话ID,用来标识当前的一次登录,通过请求地址:

https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_=1377482012272(其中1377482012272这个值是当前距离林威治标准时间的毫秒)

服务器会返回如下的字符串:

window.QRLogin.code = 200; window.QRLogin.uuid = “DeA6idundY9VKn”;

而这个DeA6idundY9VKn字符串就是微信服务器返回给我们的ID。

2.通过会话ID获得二维码

既然微信Web版本是通过二维码进行登录,如何获得这个随机的二维码呢?答案就是利用刚才获得的ID去请求服务器生成的二维码,通过上面的ID我们组合得到以下的URL地址:

https://login.weixin.qq.com/qrcode/DeA6idundY9VKn?t=webwx

该请求返回的便是我们需要的二维码,此时需要用户在微信的手机版本中扫描这个二维码(我就搞不明白微信官方是如何想的,登录Web版本竟然还需要手机微信去配合登录,难道没有考虑我被迫选择Web微信就是因为手机不在身边这样的情形么?)

3.轮询手机端是否已经扫描二维码并确认在Web端登录

当获得二维码之后,就需要用户去手机端去扫描二维码,并获得用户的授权,此时我们并不知道用户何时完成这个操作,所以我们只有轮询,而轮询的地址就是:

https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid=DeA6idundY9VKn&tip=1&_=1377482045264(注意UUID和最后时间这两个参数)

如果服务器返回:

window.code=201;

则说明此时用户在手机端已经完成扫描,但还没有点击确认;

如果服务器返回:

window.redirect_uri=一个URL地址

则说明此时用户已经在手机端完成了授权过程,保存下这个URL地址下一步骤中使用。

4.访问登录地址,获得uin和sid

通过访问上一步骤中获得的URL地址,可以在服务器返回的Cookies中获得到wxuin和wxsid这两个值,这两值在后续的通信过程中都要使用到这两个值,并且Cookies中也需要包括这两项。

5.初使化微信信息

前面的步骤算是完成了这个复杂的登录过程,如果我们需要使用微信就需要获得当前用户的信息、好友列表等,还有一个关键的就是同步信息(后续与服务器轮询中需要使用同步信息),通过访问以下的链接:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=1377482058764(r依然是时间)

访问该链接需要使用POST,并且在Body中带上以下的JSON信息:

1
2
{“BaseRequest”:
{“Uin”:“2545437902”,“Sid”:“QfLp+Z+FePzvOFoG”,“Skey”:“”,“DeviceID”:“e1615250492”}}

这个JSON串中Uin和Sid分别是上面步骤中获得的那两个Cookie值,DeviceID是一个本地生成的随机字符串(分析了官方的总是e+一串数字,所以我们也保持这样的格式)。

服务器就会返回一个很长的JSON串,这其中包括:BaseResponse中的值用来表示请求状态码,ContactList主要用来表示联系人(此列表不全,只包括了类似通讯录助手、文件助手、微信团队和一些公众帐号等,后面会通过另一接口去获得更全面的信息),SyncKey是用户与服务器同步的信息,User就是当前登录用户自己的信息。

6.获得所有的好友列表

在上一步骤中已经获得了部分好友和公众帐号,如果需要获得完整的好友信息,就需要访问以下的链接:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?r=1377482079876(r依然是时间)

访问该链接同样需要POST方式,但Body为空JSON:{},服务器对身份的判定是通过Cookies,所以需要保持之前访问的Cookies不被修改(在Objective-C中会自动保存相关的Cookies,无需程序特殊处理),在返回的JSON串中,MemberList中就包含了所有的好友信息。

7.保持与服务器的信息同步

与服务器保持同步需要在客户端做轮询,该轮询的URL如下:

https://webpush.weixin.qq.com/cgi-bin/mmwebwx-bin/synccheck?callback=jQuery18309326978388708085_1377482079946&r=1377482079876&
sid=QfLp+Z+FePzvOFoG&uin=2545437902&deviceid=e1615250492&synckey=(见以下说明)&_=1377482079876

其中的参数r和_都是time,sid,uin,deviceid与上面步骤的值相对应,此处的synkey是上步步骤获得的同步键值,但需要按一定的规则组合成以下的字符串:

1_124125|2_452346345|3_65476547|1000_5643635

就是将键和值用_隔开,不同的键值对用|隔开,但记得|需要URL编码成%7C,通过访问上面的地址,会返回如下的字符串:

window.synccheck={retcode:”0”,selector:”0”}

如果retcode中的值不为0,则说明与服务器的通信有问题了,但具体问题我就无法预测了,selector中的值表示客户端需要作出的处理,目前已经知道当为6的时候表示有消息来了,就需要去访问另一个接口获得新的消息。

8.获得别人发来的消息

当一个步骤中知道有新消息时,就需要去获取消息内容,通过访问以下的链接:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=QfLp+Z+FePzvOFoG&r=1377482079876

上面链接中的参数sid对应上面步骤中的值,r为时间,访问链接需要使用POST方式,Body中包括JSON串,该JSON串格式如下:

1
2
3
{“BaseRequest” : {“Uin”:2545437902,“Sid”:“QfLp+Z+FePzvOFoG”},
“SyncKey” : {“Count”:4,“List”:[{“Key”:1,“Val”:620310295},{“Key”:2,“Val”:620310303},{“Key”:3,“Val”:620310285},{“Key”:1000,“Val”:1377479086}]},
“rr” :1377482079876};

以下的信息中BaseRequest中包括的Uin与Sid与上面步骤中的值对应,SyncKey也是上面步骤中获得的同步键值对,rr为时间,访问成功之后服务器会返回一个JSON串,其中AddMsgList中是一个数组,包含了所有新消息。

9.向用户发送消息

用户主动发送消息,通过以下的URL地址:
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?sid=QfLp+Z+FePzvOFoG&r=1377482079876
上面的sid和r参数不再解释了,访问该URL采用POST方式,在Body中的JSON串形如以下的格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
“BaseRequest”:{
“DeviceID” : “e441551176”,
“Sid” : “S8wNi91Zry3024eg”,
“Skey” : “F820928BBA5D8ECA23448F076D2E8A915E1349E9FB4F4332”,
“Uin” : “2545437902”
},
“Msg” : {
“ClientMsgId” : 1377504862158,
“Content” : “hello”,
“FromUserName” : “wxid_2rrz8g8ezuox22”,
“LocalID” : 1377504862158,
“ToUserName” : “wxid_j4nu420ojhsr21”,
“Type” : 1
},
“rr” = 1377504864463
}

其中BaseRequest都是授权相关的值,与上面的步骤中的值对应,Msg是对消息的描述,包括了发送人与接收人,消息内容,消息的类型(1为文本),ClientMsgId和LocalID由本地生成。rr可用当前的时间。
在返回JSON结果中BaseResponse描述了发送情况,Ret为0表示发送成功。

centos低版本安装git 2.*

2017年5月2日 由 Creater 没有评论 »

centos通过yum install git安装后默认为1.7,但是不支持https与ssh私有项目clone。
升级步骤,看似简单,但是中途会出现一些错误:

wget -O git.zip https://github.com/git/git/archive/master.zip
make prefix=/usr/local/git all 
make install

前向依赖

# yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
# yum install gcc perl-ExtUtils-MakeMaker

一个更容易检测设备的JavaScript库——device.js

2017年4月28日 由 Creater 没有评论 »

decice.js的github地址(https://github.com/matthewhudson/device.js/)

device.js是一个可以用来检测设备的平台、操作系统和方向的JavaScript库。device.js 通过操作系统(比如 iOS,安卓,黑莓,Windows,Firefox OX),方向(横屏或者竖屏),类型(平板或者移动设备),来为设备添加 CSS Class,并且它还提供了一些Javascript 函数用来判断设备。
比如在PC端打开引入了device.js的 html 页面时会在标签里添加”desktop landscape”的class。
device.js的使用
直接在html页面的头部引入即可使用:

<script type="text/javascript" src="device.js"></script>

根据设备的不同生成的CSS
**Device** **CSS Classes**

iPhone ios iphone mobile

iPod ios ipod mobile

Android Phone android mobile

Android Tablet android tablet

BlackBerry Phone blackberry mobile

BlackBerry Tablet blackberry tablet

Windows Phone windows mobile

Windows Tablet windows tablet

Firefox OS Phone fxos mobile

Firefox OS Tablet fxos tablet

MeeGo meego

Desktop desktop

Television television

根据方向的不同生成的CSS
**Orientation** **CSS Classes**

Landscape landscape

Portrait portrait

相关的JavaScript方法
**Device** **JavaScript Method**

Mobile device.mobile()

Tablet device.tablet()

Desktop device.desktop()

iOS device.ios()

iPad device.ipad()

iPhone device.iphone()

iPod device.ipod()

Android device.android()

Android Phone device.androidPhone()

Android Tablet device.androidTablet()

BlackBerry device.blackberry()

BlackBerry Phone device.blackberryPhone()

BlackBerry Tablet device.blackberryTablet()

Windows device.windows()

Windows Phone device.windowsPhone()

Windows Tablet device.windowsTablet()

Firefox OS device.fxos()

Firefox OS Phone device.fxosPhone()

Firefox OS Tablet device.fxosTablet()

MeeGo device.meego()

Television device.television()

**Orientation** **JavaScript Method**
Landscape device.landscape()
Portrait device.portrait()
通常情况下,我们为了使页面在不同分辨率的设备上展示出不同的效果,会使用CSS3的 @media属性来实现,但如果我们想在 PC端和 mobile端展示两个不同的页面,使用device.js 就会方便很多,首先用它来检测设备,然后再在不同的设备上打开不同的页面。
假设有个项目,我们想让它在手机上打开的页面为 m.html,在电脑上打开的页面为 desk.html,这个时候我们就可以用device.js来实现,代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <title>device.js的使用</title>
    <script type="text/javascript" src="device.js"></script>
</head>
<body>
    <script type="text/javascript">
        var isMobile = device.mobile(),
             isTable = device.tablet();

        if(isMobile || isTable){
            window.open("m.html","_self"); //如果终端是手机或者平板,就打开m.html
        }
        else{
            window.open("desk.html","_self"); //否则打开desk.html
        }
    </script>
</body>
</html>

phpstorm10破解 服务器验证方法

2017年4月28日 由 Creater 没有评论 »

f954fda6d312fdee93f7234e2fb6a294
如果http://15.idea.lanyus.com/方法无法激活。可以将其替换为http://jetbrains.tencent.click