薪酬体系

##简介

我们相信公平和透明的薪酬机制很有益于公司的长期健康发展。我们在设计薪酬体系时重点考虑了几个问题:

  • 避免薪酬倒挂:很多公司,尤其是大的互联网公司在人才竞争激烈的年份给出较高的入职薪水,而老员工的薪水因为惯性没有相应提高,所以造成了新员工入职薪酬高于老员工的不公平现象。
  • 消除薪酬谈判带来的不公:在招聘时,很多公司往往会根据候选人之前的薪酬以及他/她的期望值在可接受的范围内确定 offer。这样的方式事实上惩罚了之前薪酬偏低的人和不善于薪酬谈判的人,而有利于之前薪酬偏高或者善于薪酬谈判的人,造成了能力和贡献相似的人薪酬产生较大差别,也就导致了组织内部的不公平。所以我们决定从机制上保证给出的 offer 完全取决于我们自己对候选人的独立评判,与其他因素无关。做到这一点,自然也就不应有任何因素导致我们对 offer 进行调整,就可以把薪酬谈判从招聘中去掉。
  • 简单透明:作为一个精简的创业公司,我们需要一个透明、自动化的机制来保证在薪酬这样的敏感问题上尽可能的公平。当人为因素越少,机制越透明时,大家就越不需要把注意力放在这些方面,日常运作也更简单高效。
  • 保持灵活性,避免线性等级:专业领域的专家和承担管理角色的同事对团队都很重要,这需要在薪酬体系中体现。

##月薪的计算

每位同事的月薪由下面的公式得出:

Salary = Function × Experience + Impact + Choice + Adjustment

其中 Function 是不同职位类型的月薪基数, 会随公司发展的情况进行调整。当前各类型的基数如下:

Function Base Amount
工程师9000
设计9000
项目经理12000
行政管理6000
商务8000
市场7000
Chief Officers13000
顾问0

以上是我们现有的职位类型,将来会根据需要增加新的类型。

Experience 是不同经验和能力等级。对于新加入的成员这个等级会根据面试情况确定。对于在职的同事,会根据实际工作情况进行定期 review 和调整。这是一个团队内部的标准,和外部的通常标准或其他公司的职称标准完全无关。Experience 所对应的数值如下表所示:

Experience Level Experience Amount
E0 0.8
E1 0.9
E2 1.0
E3 1.2
E4 1.4
E5 1.8
E6 2.0
E7 3.0

Impact 指的是在团队中的影响力和贡献,对应的数值如下图所示:

Impact Level Impact Amount
I0 0
I1 2,000
I2 4,000
I3 6,000

由于在面试中无法衡量将来在团队中的实际贡献,我们在新的 offer 中通常会把 impact 定为 I0 留待将来调整。

Choice 除联合创始人月薪的 Choice 部分为 0 外,其他同事在入职时默认 Choice 部分为月薪其他部分的 10%。我们会按期权激励计划授予每位同事期权。新同事在入职的第二个月底前可以在期权和月薪间做一个倾向性选择。选择期权的同事可以放弃月薪的 Choice 部分而在原定期权基础上多获得 20% 的期权。

Adjustment 这是一个对所有人固定的调整,目前为 1000 元。

##例子

假设某个 function 的基数是 13000,那么这个 function 的 experience level 为 E3、impact level 为 I1 的同事,她的 Function × Experience + Impact 部分就是 13000 × 1.4 + 5000 = 23200。如果她选择更多期权,那么她的月薪就是 23200 + 1000 = 24200。如果她选择更多月薪,那么她的月薪就是 23200 × 110% + 1000 = 26520。

##奖金

目前我们周期性的奖金是每年的年终奖。年终奖的金额是浮动的,规则详见 工作的评价和反馈机制。

##结语

以上的机制借鉴了 Buffer 的 Open Salaries,具体的公式按照我们的情况做了调整, 希望让每个人都能清楚自己薪酬的由来以及未来的空间,也让潜在的应聘者一目了然了解可能的薪酬范围。

所有同事的薪酬以及发给候选人的 offer 都严格遵照这个标准。我们有可能不定期地调整各类职位的基数以适应公司发展的不同阶段并保持竞争力。由于这样的调整是整体的,所以不会导致倒挂等问题。另外由于影响最大的因素是 function 和 experience,这个公式也保留了足够的灵活性。比如一个很资深并作为项目负责人的工程师薪酬完全可能达到或超过 VP 和 C-Level 级别的管理者。

任何制度都会经历在实践中完善的过程,我们会根据反馈在发展中不断地完善这个薪酬体系。

转自http://open.leancloud.cn/salary.html

换上了用Let's Encrypt Closed Beta自己签发的证书

先上图。两个小时的成果。
letsencrypt

在10月31的时候就收到了letsencrypt发的 Let’s Encrypt Closed Beta Invite‏ 说我的tms.im和www.tms.im已经加入内测白名单。可惜这封邮件被“智能”的丢进了垃圾邮件文件夹。导致我今天才看到。于是来折腾一下。

在开始之前先严重吐槽下,可能是由于内测或者该计划刚开始还不完善的原因。这个东西特别特别特别不亲民。我搞了两个多小时才签了一个证书出来。突然发现只签了tms.im没签www.tms.im。于是又用了40分钟的时间重新签了这两个。外加这货的有效期只有三个月,也就是说三个月以后我要重新签。在现在年付的付费证书已经这么便宜的情况下。到底letsencrypt有没有竞争力。

下面正文。

由于现在还是内测。官方在邮件里提供了一个内测用的API路径。

To use Let’s Encrypt’s official client to obtain your real
certificates, you will need to provide the production API URL on the
command line:

https://acme-v01.api.letsencrypt.org/directory

还提供了软件

git clone https://github.com/letsencrypt/letsencrypt cd letsencrypt
./letsencrypt-auto --agree-dev-preview --server
https://acme-v01.api.letsencrypt.org/directory auth

但是装好软件以后运行./letsencrypt-auto报错。

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-Wa1Lwq/ConfigArgParse

去官方论坛https://community.letsencrypt.org/看了一下说只支持python2.7,不支持2.6。 好吧我centos6.7默认是2.6的python。也懒得搞成2.7了,于是另开了一台centos7的服务器来签发。

执行./letsencrypt-auto --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory auth -d tms.im -d www.tms.im

   报错The program nginx (process ID 7176) is already listening on TCP port 
    80. This will prevent us from binding to that port. Please stop the  
    nginx program temporarily and then try again.      

提醒我80端口被占用。验证个域名所有权还要关80端口额。还好只是个个人博客。如果我是生产用的域名和服务器怎么办。总不能停机去搞域名验证吧。

暂时停了80的nginx。终于进到了下一步。然后又开始报错

Failed authorization procedure. tms.im (dvsni): unauthorized :: The client lacks sufficient authorization :: Correct zName not found for TLS SNI challenge

只好切换用手动模式:后面加一个
-a manual

手动模式告诉我需要自己开一个 SimpleHTTPServer 来搞验证,并且给了我一堆指令。我以为它会自动开呢。用netstat看了一下,果然没有自动开。好吧我只好手动调用python开一个SimpleHTTPServer 。然后按照每次验证它给的路径和文件名和文件内容创建对应的验证文件。

当我以为这样就可以通过验证的时候,letsencrypt告诉我还是tooyoung

:: The client lacks sufficient authorization :: Invalid response from http://tms.im/.well-known/acme-challenge/g2eyBgAf3Z-NpzBAzTrvxopLxJ1PH1I8lt7sqiA01sQ [103.242.111.8]

什么。不是已经开好SimpleHTTPServer 了么。我的SimpleHTTPServer 里也有access log啊。我在浏览器打开也可以访问啊。再仔细一看IP是103.242.111.8。这,我不是改了DNS指向验证用的这台服务器了么,为什么非要去以前的服务器验证。

可能是远程API那边DNS更新比较慢吧。可是我用nslookup看了一下主要的几个DNS服务器都更新过了啊。鬼知道他们用的什么DNS,或者是就是有机制让你不能改IP验证?谁知道呢。只好在以前的服务器上也开了个SimpleHTTPServer,放入同样的验证文件。再进行验证。

这下终于生成成功了。最新的证书和私钥都在/etc/letsencrypt/live/$domain里面。内测阶段只能签三个月的证书。

/etc/letsencrypt/keys里面存的是所有的包括之前和最新的证书。

最好把整个/etc/letsencrypt目录都备份一下,里面是包括邮箱和token之类的东西。以后renew的时候用的。

折腾了两个多小时签发出第一张免费证书。letsencrypt还有很长的路要走啊。

新玩具

新玩具

本站启用nginx的HTTP/2新特性

今天新配服务器,到nginx官网下载源码,瞬间看到

2015-09-22 nginx-1.9.5 mainline version has been released, featuring experimental HTTP/2 module.

Nginx终于原生支持HTTP/2了。早就听闻HTTP/2的一大堆优秀的新特性。马上开启尝尝鲜。

根据官网的说明,在编译的时候configure时加入–with-http_v2_module即可编译带ngx_http_v2_module的nginx

The ngx_http_v2_module module (1.9.5) provides support for HTTP/2 and
supersedes the ngx_http_spdy_module module.

This module is not built by default, it should be enabled with the
–with-http_v2_module configuration parameter.

编译成功后在conf文件里把listen 443 ssl改为 listen 443 ssl http2即可开启http2支持

server {
    listen 443 ssl http2;
}

开启完毕,马上验证一下

开启前:

开启前

开启后

开启后

速度提升将近一倍,头部压缩、压缩HTTP头等特性表现的很明显,初始化连接和ssl的损耗都已经降到最低。看来HTTP/2的优化还是很给力的,期待更多的网站支持HTTP/2

参考阅读:
Module ngx_http_v2_module
View the HTTP/SPDY/HTTP2 Protocol in Google Chrome

跨IDC数据备份

为了数据安全性。除了做了主从和多机互备份以外,在异地容灾和数据备份方面也不容忽视。
这里是实现跨IDC数据备份的一种思路。分为文件备份和数据库备份两部分。文件备份可以保证用户上传的文件,图片和网站的代码不会丢失。而数据库备份则是数据保护的重中之重。
之所以采用跨IDC进行数据备份也是考虑到数据的安全性和同IDC的网络崩溃和主机崩溃的可能性。

文件备份

文件数量和大小决定了需要做到文件同步备份必须采用增量备份的方式。传统的方法是使用 inotify + rsync 来进行同步备份。
这里采用Sersync 来进行服务器间文件同步。

配置 Slave 上的 WWW 同步

Slave上安装rsync
然后配置文件写明,其中rsync.pass里面写入密码

log file = /var/log/rsyncd.log 
pidfile = /var/run/rsyncd.pid 
lock file = /var/run/rsync.lock  
secrets file = /etc/rsyncd/rsync.pass
[tongbu]
path = /home/wwwroot/
comment = tongbu
uid = root
gid = root
port=873
use chroot = no
read only = no
list = no
max connections = 200
timeout = 600 
auth users = tms
hosts allow = 主机的IP

最后启动Rsync的 rsync –daemon

启动 Master 上的 Sersync 做数据同步

主机上配置sersync

 <sersync>
	<localpath watch="/home/wwwroot">
	    <remote ip="远程IP" name="tongbu"/>
	</localpath>

其他配置略

第一次启动加上 -r 参数做首次同步,之后就不要再加  -r 参数了
./sersync2 -n 2 -d -r -o confxml.xml

文件备份到此结束。

数据库备份

数据库备份这里采用主从的方式,而这里的slave纯粹做备份使用。无业务访问他。
前期准备工作步骤如下:
1、修改备份服务器上my.cnf中的server-id

2、登录主服务器创建同步账号GRANT REPLICATION SLAVE ON . TO ‘slave’@‘Slave服务器IP’ IDENTIFIED BY ‘password’;

备份主服务器步骤:
1、FLUSH TABLES WITH READ LOCK;

2、cp -ar /var/lib/mysql /home/DATA/tmp

3、show master status;并且记录file和position

4、UNLOCK TABLES;

复制主服务器的/home/DATA/tmp到从服务器并且替换mysql的var目录

登录从服务器的mysql

CHANGE MASTER TO
 
    ->     MASTER_HOST='master_host_name',
 
    ->     MASTER_USER='replication_user_name',
 
    ->     MASTER_PASSWORD='replication_password',
 
    ->     MASTER_LOG_FILE='前面让你记录下的 master 状态显示的 logfile 名字',
 
    ->     MASTER_LOG_POS=前面记录下的 postion;

START SLAVE;

show slave status \G

这样Master —> Slave 就运行起来了。数据库备份结束。

为了进一步的安全考虑,采用crontab每隔一天做一次全量备份,在备份服务器进行。脚本如下

#!/bin/bash
DBName=数据库名
DBUser=备份用户
DBPasswd=备份用户的密码
BackupPath=/root/Dropbox/   #保存到同步目录

LogFile=/root/db.log
DBPath=/var/lib/mysql/ #备份的数据库目录
BackupMethod=mysqldump
#BackupMethod=mysqlhotcopy
#BackupMethod=tar

NewFile="$BackupPath"db$(date +%y%m%d).tgz
DumpFile="$BackupPath"db$(date +%y%m%d)
OldFile="$BackupPath"db$(date +%y%m%d --date='5 days ago').tgz  #自动删除5天前的备份
echo "-------------------------------------------" >> $LogFile
echo $(date +"%y-%m-%d %H:%M:%S") >> $LogFile
echo "--------------------------" >> $LogFile
#Delete Old File
if [ -f $OldFile ]
then
        rm -f $OldFile >> $LogFile 2>&1
        echo "[$OldFile]Delete Old File Success!" >> $LogFile
else
        echo "[$OldFile]No Old Backup File!" >> $LogFile
fi
if [ -f $NewFile ]
then
        echo "[$NewFile]The Backup File is exists,Can't Backup!" >> $LogFile
else
        case $BackupMethod in
        mysqldump)
                if [ -z $DBPasswd ]
                then
                        mysqldump -u $DBUser --opt $DBName > $DumpFile
                else
                        mysqldump -u $DBUser -p$DBPasswd --opt $DBName > $DumpFile
                fi
                tar czvf $NewFile $DumpFile >> $LogFile 2>&1
                echo "[$NewFile]Backup Success!" >> $LogFile
                rm -rf $DumpFile
                ;;
        mysqlhotcopy)
                rm -rf $DumpFile
                mkdir $DumpFile
                if [ -z $DBPasswd ]
                then
                        mysqlhotcopy -u $DBUser $DBName $DumpFile >> $LogFile 2>&1
                else
                        mysqlhotcopy -u $DBUser -p $DBPasswd $DBName $DumpFile >>$LogFile 2>&1
                fi
                tar czvf $NewFile $DumpFile >> $LogFile 2>&1
                echo "[$NewFile]Backup Success!" >> $LogFile
                rm -rf $DumpFile
                ;;
        *)
                service mysql stop >/dev/null 2>&1
                tar czvf $NewFile $DBPath$DBName >> $LogFile 2>&1
                service mysql start >/dev/null 2>&1
                echo "[$NewFile]Backup Success!" >> $LogFile
                ;;
        esac
fi
echo "-------------------------------------------" >> $LogFile

同时采用dropbox实时上传网盘。保证每日的数据库在云端存有一份备份。