[转]centos7下mongodb安装和配置

1、下载安装包

curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.12.tgz

2、解压

tar -zxvf mongodb-linux-x86_64-3.2.12.tgz

3、移动到指定位置

mv  mongodb-linux-x86_64-3.2.12/ /usr/local/mongodb

4、在/usr/local/mongodb下创建文件夹

mkdir -p /data/db
mkdir  /logs

5、在/usr/local/mongodb/bin下新建配置

vi mongodb.conf

dbpath = /usr/local/mongodb/data/db #数据文件存放目录

logpath = /usr/local/mongodb/logs/mongodb.log #日志文件存放目录
port = 27017  #端口
fork = true  #以守护程序的方式启用,即在后台运行
nohttpinterface = true
auth=true

bind_ip=0.0.0.0

6、环境变量配置

vi /etc/profile

export MONGODB_HOME=/usr/local/mongodb

export PATH=$PATH:$MONGODB_HOME/bin

保存后,重启系统配置

source /etc/profile

7、启动

在/usr/local/mongodb/bin下

mongod -f mongodb.conf 或 ./mongod -f mongodb.conf

8、关闭

mongod -f ./mongodb.conf –shutdown  或./mongod -f ./mongodb.conf –shutdown

9、开启端口

firewall-cmd –zone=public –add-port=27017/tcp –permanent
查看端口
firewall-cmd –permanent –query-port=27017/tcp
重启防火墙

firewall-cmd –reload

10、创建用户

 创建用户管理员:
   use admin
   db.createUser({user:"root",pwd:"root123456",roles:["userAdminAnyDatabase"]})
   db.auth('root','root123456')
 以用户管理员身份登录,并切换数据库,创建数据库用户:
   切换到test数据库
   use test
   创建用户名、密码、角色
   db.createUser({user:"username",pwd:"@user123456*",roles:[{role:"readWrite",db:"securitydata"}]})
   设置mongodb配置中的auth为true(/etc/mongod.conf):
   security:
     authorization: enabled
   验证mongodb数据库权限。
   db.auth('user','@user123456*')

[转]Golang中生成良好的唯一ID的方式

想像一下你正在开发一个记事本App。
每一条记事都需要一个唯一ID。
如果你能协调,生成唯一ID是一件非常简单的事。
最简单的方式就是通过使用数据库:使用AUTOINCREMENT属性的列,然后当你插入一条新的记事的时候,数据库将会生成一个唯一ID。

但假如你不能协调呢?
列如,你想要你的App离线的时候也能生成唯一ID,这时候它是无法连接上数据库的。

在无法协调的情况下生成唯一ID的请求通常来自于分布式系统。
一个简单的解决方案是生成一个随机ID。
假如你使用16字节长度的随机串,将不存在产生一样的随机串的几率。
这是一个常见的问题,30多年前我们为此创建了一个名为UUID / GUID的标准。

我们可以比GUID做的更好,一个好的随机唯一ID遵循以下原则:
1、唯一性:基本原则,必须满足。
2、可排序的:可以使用随机唯一ID字符串进行排序。
3、具有时间属性:同一时间内,生成的ID彼此相近。
4、随机唯一ID字符串无需转义就要以做为URL的一部份。
5、越短越好。

使用Go实现的类似代码不多,它们遵循以下规则:
1、使用时间做为ID的一部份,使ID具有时间属性。
2、使用随机数据填充剩余的部份。
3、编码唯一ID为字符串,满足可排序及URL安全的条件。

下面列出的是一些生成唯一ID的Go包,以及它们生成的ID字符串的格式:

Package Id Format
github.com/segmentio/ksuid 0pPKHjWprnVxGH7dEsAoXX2YQvU 4 bytes of time (seconds) + 16 random bytes
github.com/rs/xid b50vl5e54p1000fo3gh0 4 bytes of time (seconds) + 3 byte machine id + 2 byte process id + 3 bytes random
github.com/kjk/betterguid -Kmdih_fs4ZZccpx2Hl1 8 bytes of time (milliseconds) + 9 random bytes
github.com/sony/sonyflake 20f8707d6000108 ~6 bytes of time (10 ms) + 1 byte sequence + 2 bytes machine id
github.com/oklog/ulid 01BJMVNPBBZC3E36FJTGVF0C4S 6 bytes of time (milliseconds) + 8 bytes random
github.com/chilts/sid 1JADkqpWxPx-4qaWY47~FqI 8 bytes of time (ns) + 8 random bytes
github.com/satori/go.uuid 5b52d72c-82b3-4f8e-beb5-437a974842c UUIDv4 from

你可以刷新测试页面看看不同时间ID格式的变化。
使用不同的包生成唯一ID的实例代码:

import (
    "github.com/chilts/sid"
    "github.com/kjk/betterguid"
    "github.com/oklog/ulid"
    "github.com/rs/xid"
    "github.com/satori/go.uuid"
    "github.com/segmentio/ksuid"
    "github.com/sony/sonyflake"
)

// To run:
// go run main.go

func genXid() {
    id := xid.New()
    fmt.Printf("github.com/rs/xid:           %s\n", id.String())
}

func genKsuid() {
    id := ksuid.New()
    fmt.Printf("github.com/segmentio/ksuid:  %s\n", id.String())
}

func genBetterGUID() {
    id := betterguid.New()
    fmt.Printf("github.com/kjk/betterguid:   %s\n", id)
}

func genUlid() {
    t := time.Now().UTC()
    entropy := rand.New(rand.NewSource(t.UnixNano()))
    id := ulid.MustNew(ulid.Timestamp(t), entropy)
    fmt.Printf("github.com/oklog/ulid:       %s\n", id.String())
}

func genSonyflake() {
    flake := sonyflake.NewSonyflake(sonyflake.Settings{})
    id, err := flake.NextID()
    if err != nil {
        log.Fatalf("flake.NextID() failed with %s\n", err)
    }
    // Note: this is base16, could shorten by encoding as base62 string
    fmt.Printf("github.com/sony/sonyflake:   %x\n", id)
}

func genSid() {
    id := sid.Id()
    fmt.Printf("github.com/chilts/sid:       %s\n", id)
}

func genUUIDv4() {
    id := uuid.NewV4()
    fmt.Printf("github.com/satori/go.uuid:   %s\n", id)
}

func main() {
    genXid()
    genKsuid()
    genBetterGUID()
    genUlid()
    genSonyflake()
    genSid()
    genUUIDv4()
}

完整的实例代码请查看:generate-unique-id/main.go

我该使用哪一个包?

上面所列的所有包都很不错。
但个人更喜欢rs/xidsegmentio/ksuid这两个包。
oklog / ulid允许使用自定义熵(随机)源,但需要使用复杂的API。
sony / sonyflake是最小的但也是最随机的。 它基于Twitter的设计,用于为推文生成ID。
为简单起见,示例代码序列化了base16 中的sony / snoflake。 在其他库使用的base62编码中它会更短,但是其他库提供了开箱即用的功能,对于sony / snoflake,我必须自己实现它。
最后一个是来自RFC 4112的UUID v4,用于比较。

作者:aidenliu
链接:https://www.jianshu.com/p/0a3fe7dad84c
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

redis 安装

$ wget http://download.redis.io/releases/redis-2.8.3.tar.gz

$ tar xzf redis-2.8.3.tar.gz

$ cd redis-2.8.3

$ make

mkdir /usr/local/redis

cp redis.conf /usr/local/redis

cd src

cp redis-server /usr/local/redis

cp redis-benchmark /usr/local/redis

cp redis-cli /usr/local/redis

cd /usr/local/redis

redis-server redis.conf

 

然后用客户端测试一下是否启动成功。

$ redis-cli

redis> set foo bar

OK

redis> get foo

“bar”

 

 

安装过程若出现 (参照: http://blog.csdn.net/luyee2010/article/details/18766911

wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz

sudo tar xzvf tcl8.6.1-src.tar.gz -C /usr/local/

cd /usr/local/tcl8.6.1/unix/

sudo ./configure

sudo make

sudo make install

 

 

 

vim /usr/local/redis.conf

#查找daemonize no改为

daemonize yes

 

修改appendonly为yes

指定是否在每次更新操作后进行日志记录,

 

#查看redis是否己启动

 

ps -ef | grep redis

 

redis-cli -h 127.0.0.1 -p 6379 shutdown

Let’s Encrypt证书部署 HTTPS

1安装

sudo yum install epel-release
sudo yum install certbot

2修改Nginx配置

location ~ /.well-known {
root /Golang/src/tallybook;
allow all;
}

3生成证书

sudo certbot certonly -a webroot –webroot-path=/Golang/src/tallybook -d tallybook.teyiqi.com

 

4nginx中的server加上

ssl 配置开始 ###
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/tallybook.teyiqi.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tallybook.teyiqi.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers ‘ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA’;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
### SSL 配置结束 #####

 

 

当证书成功获取后,用下面命令测试是否可以续期,此命令只是测试用,不会更新证书

certbot renew --dry-run 

 

crontab -e

30 4 * * 1 certbot renew --renew-hook "systemctl restart nginx" --quiet > /dev/null 2>&1 &


设置了每周一凌晨4点30自动更新证书,如果更新成功就自动重启nginx服务,证书在到期前30天内才能更新,多余的更新会自动忽略掉的,每周更新还有一个好处是更新可能会失败,这样最多还有4次的尝试机会来保证不会过期.
修改好后保存退出。

beego创建API项目

1,beego api


Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。
项目地址是:http://swagger.io/
使用 beego 开发自带集成了 swagger的东西。
https://beego.me/docs/advantage/docs.md
github 地址:
https://github.com/beego/swagger
beego 使用最新的版本:1.8.0

2,非常的方便


创建一个项目:apiserver

bee api apiserver
cd apiserver/
bee run -gendoc=true -downdoc=true
  • 1
  • 2
  • 3

会自动下载最新的 swagger 压缩文件:

2017/04/06 20:52:08 INFO     ▶ 0001 Using 'apiserver' as 'appname'
2017/04/06 20:52:08 INFO     ▶ 0002 Loading default configuration...
2017/04/06 20:52:08 INFO     ▶ 0003 Downloading 'https://github.com/beego/swagger/archive/v2.zip' to 'swagger.zip'...
2017/04/06 20:52:21 SUCCESS  ▶ 0004 800610 bytes downloaded!
  • 1
  • 2
  • 3
  • 4

启动成功,直接访问就可以了:
http://localhost:8080/swagger/#/user

linux 安装GO

1、下载二进制文件:

wget https://storage.googleapis.com/golang/go1.7.3.linux-amd64.tar.gz
  • 1

2、解压并创建工作目录:

tar -zxf go1.7.3.linux-amd64.tar.gz -C /usr/local/
mkdir /Golang
  • 1
  • 2

3、设置环境变量:

在 /etc/profile 添加:

export GOROOT=/usr/local/go 
export GOBIN=$GOROOT/bin
export GOPKG=$GOROOT/pkg/tool/linux_amd64 
export GOARCH=amd64
export GOOS=linux
export GOPATH=/Golang
export PATH=$PATH:$GOBIN:$GOPKG:$GOPATH/bin

然后执行 source /etc/profile 使之生效或者重新登录Linux也可。

 

查看环境变量是否生效

go env

(转)o(1), o(n), o(logn), o(nlogn)

在描述算法复杂度时,经常用到o(1), o(n), o(logn), o(nlogn)来表示对应算法的时间复杂度, 这里进行归纳一下它们代表的含义:
这是算法的时空复杂度的表示。不仅仅用于表示时间复杂度,也用于表示空间复杂度。
O后面的括号中有一个函数,指明某个算法的耗时/耗空间与数据增长量之间的关系。其中的n代表输入数据的量。
比如时间复杂度为O(n),就代表数据量增大几倍,耗时也增大几倍。比如常见的遍历算法。
再比如时间复杂度O(n^2),就代表数据量增大n倍时,耗时增大n的平方倍,这是比线性更高的时间复杂度。比如冒泡排序,就是典型的O(n^2)的算法,对n个数排序,需要扫描n×n次。
再比如O(logn),当数据增大n倍时,耗时增大logn倍(这里的log是以2为底的,比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度)。二分查找就是O(logn)的算法,每找一次排除一半的可能,256个数据中查找只要找8次就可以找到目标。
O(nlogn)同理,就是n乘以logn,当数据增大256倍时,耗时增大256*8=2048倍。这个复杂度高于线性低于平方。归并排序就是O(nlogn)的时间复杂度。
O(1)就是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。 哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话)

昨天看了nginx的加权轮询的平滑算法后,自己尝试编写的PHP程序

原文地址 http://blog.csdn.net/zhangskd/article/details/50194069

每个后端peer都有三个权重变量,先解释下它们的含义。

(1) weight

配置文件中指定的该后端的权重,这个值是固定不变的。

(2) effective_weight

后端的有效权重,初始值为weight。

在释放后端时,如果发现和后端的通信过程中发生了错误,就减小effective_weight。

此后有新的请求过来时,在选取后端的过程中,再逐步增加effective_weight,最终又恢复到weight。

之所以增加这个字段,是为了当后端发生错误时,降低其权重。

(3) current_weight

后端目前的权重,一开始为0,之后会动态调整。那么是怎么个动态调整呢?

每次选取后端时,会遍历集群中所有后端,对于每个后端,让它的current_weight增加它的effective_weight,

同时累加所有后端的effective_weight,保存为total。

如果该后端的current_weight是最大的,就选定这个后端,然后把它的current_weight减去total。

如果该后端没有被选定,那么current_weight不用减小。

 

弄清了三个weight字段的含义后,加权轮询算法可描述为:

1. 对于每个请求,遍历集群中的所有可用后端,对于每个后端peer执行:

peer->current_weight += peer->effecitve_weight。

同时累加所有peer的effective_weight,保存为total。

2. 从集群中选出current_weight最大的peer,作为本次选定的后端。

3. 对于本次选定的后端,执行:peer->current_weight -= total。

 

上述描述可能不太直观,来看个例子。

现在使用以下的upstream配置块:

upstream backend {

server a weight=4;

server b weight=2;

server c weight=1;

}

按照这个配置,每7个客户端请求中,a会被选中4次、b会被选中2次、c会被选中1次,且分布平滑。

我们来算算看是不是这样子的。

initial current_weight of a, b, c is { 0, 0, 0 }

 

通过上述过程,可得以下结论:

1. 7个请求中,a、b、c分别被选取了4、2、1次,符合它们的权重值。

2. 7个请求中,a、b、c被选取的顺序为a, b, a, c, a, b, a,分布均匀,权重大的后端a没有被连续选取。

3. 每经过7个请求后,a、b、c的current_weight又回到初始值{ 0, 0, 0 },因此上述流程是不断循环的。

这个平滑的加权轮询算法背后应该有数学论证,这里就不继续研究了:)

 

然后自己写的PHP

 

<?php
class roundLzx{
    public $weight = array();
    public $current = array();
    public $selArr = array();
    public $first = false;

    public function __construct($arr){
        foreach ($arr as $k => $v){
            $this->weight[$k] = $v;
            $this->current[$k] = 0;
        }
        $this->first = true;
    }

    public function getServer(){
        $total = 0;
        if ($this->isEnd() == true && $this->first == false){
            return true;
        }
        $this->first = false;
        foreach ($this->current as $k => $v){
            $this->current[$k] += $this->weight[$k];
            $total += $this->weight[$k];
        }
        //获取最大值
        $sel = $this->maxValue();
        $this->current[$sel] = $this->current[$sel]-$total;
        array_push($this->selArr, $sel);
        if ($this->getServer()){
            return true;
        }
    }
    public function maxValue(){
        $arr=$this->current;
        asort($arr);
        $rel=array();
        foreach($arr as $k=>$v){
            $rel[]=$k;
        }
        return end($rel);
    }

    public function isEnd(){
        $num = 0;
        foreach ($this->current as $k => $v) {
            if ($v == 0){
                $num++;
            }
        }
        return ($num == count($this->current)) ? true : false;
    }
}
$arr = array('a' => 4, 'b' => 2, 'c' => 1);
$obj = new roundLzx($arr);
if ($obj->getServer()){
    print_r($obj->selArr);
}