gitbook配置

gitbook配置



{ "title": "标题", "author": "crisen", "description": "描述", "language": "zh-cn", "gitbook": "3.2.3", "structure": { "readme": "README.md" }, "links": { "sidebar": { "crisen": "https://www.crisen.org" } }, "plugins": [ "-lunr", "-search", "search-plus", "expandable-chapters-small", "edit-link", "advanced-emoji", "anchors", "sitemap-general", "copy-code-button", "alerts", "ace", "splitter", "-sharing", "anchor-navigation-ex-toc", "theme-api" ], "pluginsConfig": { "edit-link": { "base": "http://github.com/crisenchou/docs/edit/master", "label": "编辑" }, "sitemap-general": { "prefix": "http://www.crisen.org" }, "theme-api": { "theme": "light" } } }

gitlab-ci-yml配置

.gitlab-ci.yml

.gitlab-ci.yml是从7.12版本开始启用的项目CI配置文件,本文件应该放在项目的根目录中,里边描述了你的项目应该如何构建。

一个yaml文件定义了一组各不相同的job,并定义了它们应该怎么运行。这组jobs会被定义为yaml文件的顶级元素,并且每个job的子元素中总有一个名为script的节点。

A set of jobs,强调是Set所以名称必须不同。

job1:
    script: "job1的执行脚本命令(shell)“

job2:
    script:
        - "job2的脚本命令1(shell)"
        - “job2的脚本命令2(shell)”

上述的文件是最简单的CI配置例子,每个job都执行了不同的命令,其中job1只执行了1条命令,job2通过数组的定义按顺序执行了两条命令。

当然,每个命令可以直接执行代码(./configure;make;make install)或者在仓库目中运行另一个脚本(test.sh)。

Job配置会被Runner读取并用于构建项目,并且在Runner的环境中被执行。很重要的一点是,每个job都会独立的运行,相互间并不依赖。

Each job is run independently from each other.

下边是一个比较复杂的CI配置文件例子:

image: ruby:2.1
services:
  - postgres

before_script:
  - bundle install

after_script:
  - rm secrets

stages:
  - build
  - test
  - deploy

job1:
  stage: build
  script:
    - execute-script-for-job1
  only:
    - master
  tags:
    - docker

以下是一些保留字,这些单词不能被用于命名job:

保留字 必填 介绍
image 构建使用的Docker镜像名称,使用Docker )作为Excutor时有效}
services 使用的Docker服务,使用Docker 作为Excutor时有效
stages 定义构建的stages
types stages的别名
before_script 定义所有job执行之前需要执行的脚本命令
after_script 定义所有job执行完成后需要执行的脚本命令
variables 定义构建变量
cache 定义一组文件,该组文件会在运行时被缓存,下次运行仍然可以使用

image和services

这两个关键字允许用户自定义运行时使用的Docker image,及一组可以在构建时使用的Service。这个特性的详细说明在 Docker integration – GitLab Documentation中。

before_script

被用于定义所有job被执行之前的命令,包括部署构建环境。它可以是一个数组元素或者一个多行文本元素。

after_script

Gitlab8.7及GitlabRunner1.2以上才支持本关键字

被用于定义所有job被执行完之后要执行的命令。同样可以是一个数组或者一个多行文本。

stages

用于定义可以被job使用的stage. 定义stages可以实现柔性的多stage执行管道。

The specification of stages allows for having flexible multi stage pipelines.

stages定义的元素顺序决定了构建的执行顺序:

  1. 同样stage的job是并行执行的。
  2. 下一个stage的jobs是当上一个stage的josb全部执行成功后才会执行。

让我们看一个简单的例子,以下有3个stage:

stages:
    - build
    - test
    - deploy
  1. 首先,所有stage属性为build的job会被并行执行.
  2. 如果所有stage属性为build的job都执行成功了,stage为test的job会被并行执行。
  3. 如果所有stage为test的job都执行成功了,则stage为deploy的job会被并行执行。
  4. 如果所有stage为deploy的job都执行成功了,则提交被标记为success。
  5. 如果任何一个前置job失败了,则提交被标记为failed并且任何下一个stage的job都不会被执行。

两个有价值的提示:

  1. 如果配置文件中没有定义stages,那么默认情况下的stages属性为build、test和deploy。
  2. 如果一个job没有定义stage属性,则它的stage属性默认为test。

types

stages的别名。

variables

从Runner0.5.0开始支持

GitlabCI允许你在.gitlab-ci.yml文件中设置构建环境的环境变量。这些变量会被存储在git仓库中并用于记录不敏感的项目配置信息,例如:

variables:
  DATABASE_URL: "postgres://postgres@postgres/my_database"

这些变量会在之后被用于执行所有的命令和脚本。Yaml配置的变量同样会被设置于所有被建立的service容器中,这可以让使用更加方便。variables同样可以设置为job级别的属性。

除了用户自定义的变量外,同样有Runner自动设置的变量。例如说CI_BUILD_REF_NAME,这个变量定义了正在构建的git仓库的branch或者tag的名称。

除了在.gitlab-ci.yml中设置的非敏感变量外,Gitlab的UI中还提供了设置敏感变量的功能。

更多关于变量的说明

cache

Runner0.7.0之后被介绍

用于定义一系列需要在构建时被缓存的文件或者目录。只能定义在项目工作环境中的目录或者文件。

cache is used to specify a list of files and directories which should be cached between builds.

默认情况下缓存功能是对每个job和每个branc都开启的。

如果cache在job元素之外被蒂尼,这意味着全局设置,并且所有的job会使用这个设置。以下是一些例子:

  • 缓存所有在binaries目录中的文件和.config文件:
rspec:
  script: test
  cache:
    paths:
    - binaries/
    - .config
  • 缓存所有git未追踪的文件
rspec:
  script: test
  cache:
    untracked: true
  • 缓存所有git未追踪的文件和在binaries目录下的文件
rspec:
  script: test
  cache:
    untracked: true
    paths:
    - binaries/
  • job级别定义的cache设置会负载全局级别的cache配置。该例子将仅缓存目录binaries
cache:
  paths:
  - my/files

rspec:
  script: test
  cache:
    paths:
    - binaries/

cache功能仅提供最努力的支持,但不要指望它总能生效。更多的实现细节,可以参阅GitlabRunner。

The cache is provided on a best-effort basis, so don’t expect that the cache will be always present.

cache:key

Runner1.0.0中被介绍

key允许你在不同的job之间定义cache的种类,例如所有job共享的cache单例、一个job一个的cache、一个branch一个的cache等等。

这允许你更便利的使用缓存,允许你在不同的job甚至不同的branche间共享缓存。

cache:key变量可以使用任何之前定义的变量。

例子

  • 缓存每个job
cache:
  key: "$CI_BUILD_NAME"
  untracked: true

缓存每个branch

cache:
  key: "$CI_BUILD_REF_NAME"
  untracked: true

缓存每个job和branch

cache:
  key: "$CI_BUILD_NAME/$CI_BUILD_REF_NAME"
  untracked: true

缓存每个branch和每个stage

cache:
  key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME"
  untracked: true

这段感觉怎么翻译都啰嗦,就这样吧

如果是在Windows环境下开发,需要使用%代替$标识环境变量:

cache:
  key: "%CI_BUILD_STAGE%/%CI_BUILD_REF_NAME%"
  untracked: true

Jobs

.gitlab-ci.yml允许配置无限个job。每个job必须有一个唯一的名称,并且不能是前文所说的任何一个保留字。一个job由一系列定义构建行为的参数组成。

job_name:
  script:
    - rake spec
    - coverage
  stage: test
  only:
    - master
  except:
    - develop
  tags:
    - ruby
    - postgres
  allow_failure: true
关键字 必要性 介绍
script 定义了Runner会执行的脚本命令
image 使用Docker镜像,多内容参考使用Docker镜像
services 使用Docker服务,更多内容参考 使用Docker镜像
stage 定义构建的stage(默认:test
type stage的别名
variables 定义job级别的环境变量
only 定义一组构建会创建的git refs
except 定义一组构建不会创建的git refs
tags 定义一组tags用于选择合适的Runner
allow_failure 允许构建失败。失败的构建不会影响提交状态。
when 定义什么时候执行构建。可选:on_successon_failurealwaysmanual
dependencies 定义当前构建依赖的其他构建,然后你可以在他们之间传递artifacts
artifacts 定义一组构建artifact。
cache 定义一组可以缓存以在随后的工作中共享的文件
before_script 覆写全局的before_script命令
after_script 覆写全局的after_script命令
environment 定义当前构建完成后的运行环境的名称

script

这是一个或一组会被Runner执行的shell脚本。例如:

jobA:
  script: "bundle exec rspec"

jobB:
  script:
    - uname -a
    - bundle exec rspec

有时候,script命令需要被包在双引号或者单引号之间。例如,包含符号(:)的命令需要写在引号中,这样yaml的解析器才能正确的解析,而不会误以为这是一组键值对。在使用包含以下符号的命令时要特别小心:
:{}[],&*#?|-<>=!%@、```

stage

stage 允许分组构建不同的stage。构建相同的stage时是并行进行的。更多关于stages的说明可以参阅stages.

only and except

onlyexcept 是管理job在被构建时的refs策略的的参数。

  1. only 设置了需要被构建的branches和tags的名称。
  2. except 设置了不需要被构建的branches和tags的名称。

这里有一些使用refs策略的规则:

  • onlyexcept 是可以相互包含的。如果一个job中 onlyexcept都被定义了,ref会同时被 only 过滤 except
  • onlyexcept 支持正则表达式。
  • onlyexcept 可以使用这几个关键字: branches, tagstriggers
  • onlyexcept 允许通过定义仓库路径的方式来过滤要fork的job。

在以下的例子中,job将只会启动以issue-开头的refs,并且跳过所有的branches。

job:
    # 使用正则
    only:
        - /^issue-.*$/
  # 使用关键字
    except:
        - branches

在下边的例子中,job将仅对被打了tag的refs,或者是被API触发器触发时
才执行:

job:
  # 使用关键字
  only:
    - tags
    - triggers

仓库路径可以用于让job仅为父仓库执行并且不fork:

The repository path can be used to have jobs executed only for the parent repository and not forks:

job:
  only:
    - branches@gitlab-org/gitlab-ce
  except:
    - master@gitlab-org/gitlab-ce

上述的例子将会为除了master以外的所有的branches运行job

job variables

可以通过使用variables定义job级别的构建变量。

gitlab runner 安装

gitlab runner 安装

  • 平台GNU/LINUX
  • x86_64 架构

获取安装脚本

 # Linux x86-64
sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64

给予可执行权限

 sudo chmod +x /usr/local/bin/gitlab-runner

如果是docker的gitlab 则可选择安装docker

 curl -sSL https://get.docker.com/ | sh

创建gitlab runner用户

 sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash

启动gitlab runner服务

 sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
 sudo gitlab-runner start

命令行下的ssh小窍门

ssh工具小窍门

对于经常和linux服务器打交道的人来说,使用ssh登录服务器肯定是家常便饭了,当然登录非常简单,使用下面的命令就可以登录了

ssh user@ip_address -p port

如果你windwos环境下,你或许会使用putty或者xshell这样可视化工具来保存你的登录凭证,用以快速方便的登录你的服务器去执行一些命令,更有甚者还会部署一些http网页面板形式的客户端来做这些操作.

其实我想说的是,这些操作除了特殊的场合之外,根本就是本末倒置了.ssh本身其实已经提供了这个简化登录的功能.接下来就让我们来体验一下 命令行的ssh带来的极致体验吧

.ssh目录

正常来说,如果我们需要远程登录linux服务器,那么我们一定会有一个terminal(终端),因此我们所有做的一切操作都应该是在命令行下呈现的,对于不会使用linux的普通用户,不包含在本文的涵盖范围内

一般来linux下我们都应该会有一个.ssh目录,一般在~/.ssh这个位置,里面保存我们的ssh登录信息

# 文件结构如下
~$ tree
.
├── authorized_keys
├── config
├── id_rsa
├── id_rsa.pub
└── known_hosts
  • authorized_keys ssh服务器的已授权秘钥信息
  • ssh config文件
  • id_rsa ssh默认的私钥文件
  • id_rsa.pub ssh默认的公钥文件
  • known_host ssh已知主机足迹

当然,如果你的目录甚至没有这些文件,甚至连.ssh目录都没有的话,也没有关系,ssh已经很贴心的为我们准备好这些东西了

生成自己的秘钥对

一般来说,ssh登录是不需要输入密码的,输入密码不仅不安全,而且效率低下,使用秘钥登录才是安全又正确的做法,所以我们首先需要一个秘钥

使用ssh-keygen命令,然后一路回车就能得到一个秘钥对了,当然如果你想个性化一点,比如想要配置一个自己的邮箱什么的,可以使用下面的命令

ssh-keygen -t rsa -C "crisen@crisen.org"

然后一路回车就可以得到你的密钥对了

拷贝自己的公钥到服务器

当然仅仅有公钥还是不能无密码登录的,你还需要把你的公钥(id_rsa.pub)里面的内容拷贝到服务器的authorized_keys文件中,当然你可以自己用密码登录到服务器,然后用vim打开authorized_keys,接着把你的公钥文件的内容复制进去,只是强大的ssh工具怎么能允许如此低下的操作呢?

  • 强大的ssh-copy-id命令会来解决你的烦恼
# 拷贝公钥到服务器
# user对应你需要登录的用户名 一般来说都是root
# ip_address 对应服务器的ip地址
sh-copy-id  user@ip_address

使用这个命令之后,系统会提示你需要输入密码,然后使用

ssh user@ip_address

就能直接登录服务器了,这样就非常方便了吧? 不,其实还不够,因为我懒得连用户和ip地址都不想输入

便捷的config文件

如果你仅仅只有一台服务器,并且ip地址很好记的话,使用ssh user@ip_address的方式确实是足够了,但是如果我几十台linux服务器,并且每个服务器的ip都没有规律并且很复杂呢?想想都觉得可怕吧,正常人是不可能记得住那么多ip的,所以贴心的ssh已经帮我们准备好了config文件,可以让你为每一个服务器设置别名

现在假设我有三台服务器,分别如下

服务器名称 登录用户 服务器地址 服务器端口
web服务器 www 192.168.1.11 22
mysql服务器 mysql 192.168.10.11 2222
redis服务器 redis 192.168.100.11 2200

不同段的ip地址,不同的登录用户,不同的登录端口,使用ssh登录看起来是不是感觉要疯,很难记得住吧,接下来让我们配置一下config文件

一般来说这个文件是不存在,因此需要我们手动创建,名字就是config,位置为~/.ssh/config

# 使用vim命令编辑config文件
vim ~/.ssh/config

# 配置下面的内容

Host www
    hostname 192.168.1.11
    user www
    port 22
Host mysql
    hostname 192.168.10.11
    user mysql
    port 2222
Host redis
    hostname 192.168.100.11
    user redis
    port 2200
  • Host 对应服务器的别名 也就是登录的标识
  • hostname 服务器的ip地址
  • user 登录的用户
  • port ssh端口

配置好以后,接下来登录服务器就简单了

# 登录web服务器
ssh www
# 登录mysql
ssh mysql
# 登录redis
ssh redis

这个配置不仅仅可以给ssh命令使用哦,你甚至可以在scp的时候使用这个别名

# 拷贝web服务器的www目录到本地当前目录
scp -r www:/data/wwwroot/www   ./

尾语

这样看起来命令行下使用ssh是不是比图形界面更加的高效简洁呢?赶紧打开你的终端试试吧

arch linux安装

arch linux安装

如果你热爱linux,那么请安装一次arch linux,它会带给人不一样的安装过程.

准备工作

我的硬件环境(虚拟机)
  • 内存: 1G
  • 硬盘 : 8G
软件

arch linux 安装镜像

安装过程

首先创建虚拟机,并将arch linux的虚拟镜像文件放到虚拟机的虚拟光驱中,然后启动虚拟机进入arch linux选择界面, 选择Boot Arch Linux 进入安装环境

磁盘分区

首先使用fdisk工具进行磁盘分区,至少包括 /目录以及swap交换目录两个分区

sudo fdisk /dev/sda
# 进入fdisk交互式工具以后 创建两个分区 
# /dev/sda1 8G   
# /dev/sda1 2G

# 格式化分区
mkfs.ext4  /dev/sda1  # 格式化根目录挂载点
mkswap   /dev/sda2 # 格式化交换目录
swapon  /dev/sda2 
挂载根目录
mount /dev/sda1  /mnt
安装基础系统到mnt
pacstrap  /mnt  base
配置fstab (配置完成之后 注意检查/mnt/etc/fstab 和当前的分区是否一致)
genfstab -U /mnt >> /mnt/etc/fstab
Chroot
arch-chroot  /mnt
设置时区
ln -sf /usr/share/zoneinfo/Asian/Shanghai  /etc/localtime
配置本地化
vi /etc/locale.gen
    en_US.UTF-8 
    zh_CN.UTF-8

locale-gen

vi /etc/locale.conf
    LANG=en_US.UTF-8
配置主机名
echo "your-hostname" > /etc/hostname
设置root密码
passwd
安装grub引导
pacman  -S grub os-prober
grub-install --target=i386-pc  --recheck  /dev/sda
grub-mkconfig  -o /boot/grub/grub.cfg
安装完成
exit
umount -R /mnt
reboot

重启如果太快没来得及删除虚拟光驱,并且直接进入了arch linux的选择界面,可以选择boot existing OS 进入新安装的arch linux

总结

安装arch linux虽然看起来很复杂,但是实际上只有4个步骤而已

  • 分区
  • 安装系统
  • 个性化(设置时区,语言文件,密码,主机名)
  • 安装grub引导

mysql主从配置与mysql-router

系统环境

服务器A

  • 操作系统: ubuntu-server 18.0.4
  • ip地址: 10.0.1.180

  • mysql版本: mysql 8.0 (主服务器)

  • mysql-router版本: mysql-router 8.0

服务器B

  • 操作系统: ubuntu-server 18.0.4
  • ip地址: 10.0.1.181
  • mysql版本: mysql-8.0 (从服务器)

ps:从服务器的mysql版本尽量和主服务器一致,或者高于主服务器的版本

宿主机(测试用)

  • 操作系统: ubuntu 16.0.4
  • ip地址: 10.0.1.189
  • mysql版本: 5.7

任务目标

配置虚拟机A的mysql为主服务器,虚拟机B的mysql为从服务器,然后使用mysql-router对当前的主从配置服务器进行管理,最后模拟客户端链接测试

软件安装

  • 安装mysql-server和mysql-router

获取mysql的apt完整包

wget https://dev.mysql.com/get/mysql-apt-config_0.8.11-1_all.deb

安装

sudo dpkg -i mysql-apt-config_0.8.11-1_all.deb
 sudo apt update

安装mysql8.0和mysql-router8.0

sudo apt install mysql-server
 sudo apt install mysql-router

虚拟机B安装同上

主从服务器配置

  • 服务器A(主服务器)

编辑/etc/mysql/mysql.conf.d/mysqld.cnf ,配置server-id 并开启二进制日志

log_bin         = mysql-bin
server-id       = 1

重启mysql服务

sudo service mysql restart

登录mysql终端,然后创建从服务器账户,并授权

mysql> CREATE USER 'slave'@'10.0.1.181' IDENTIFIED BY '123456'; 
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@'10.0.1.181';
mysql> flush privileges;

查看主服务器状态

mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000002
         Position: 1901
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.00 sec)
  • 同步服务器A的初态到服务器B

导出服务器A的数据 并拷贝到服务器B的home目录下

# 服务器A 
mysqldump -uroot -p --all-databases > db.sql
scp db.sql crisen@10.0.1.181:~/

导入服务器A的数据

# 服务器B
mysql > source db.sql;
  • 服务器B (从服务器)

编辑/etc/mysql/mysql.conf.d/mysqld.cnf ,配置server-id等从服务器配置

log_bin           = mysql-bin # 可选
server-id         = 2
relay_log         = /var/log/mysql/mysql-relay-log
log_slave_updates = 1
read_only         = 1

配置主服务器

mysql > change master to master_host='10.0.1.180',
     -> master_user='slave',
     ->  master_password='123456',
     ->  master_log_file='mysql-bin.000002',
     ->   master_log_pos=1901;

启动复制

mysql > start slave;

查看从服务器状态

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.0.1.180
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 1901
               Relay_Log_File: mysql-relay-log.000002
                Relay_Log_Pos: 1777
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            ........ 省略 ..........
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates

Slave_IO_Running和Slave_SQL_Running同时为Yes的时候 就说明主从配置是成功 如果没有配置成功 可以通过查看Slave_SQL_Running_State的状态来检查错误原因

mysql router 配置

虽然很多的框架提供了让你可以把读写操作配置到不同的数据库上,但那是比较简单的情况下,更加复杂的情况当然是选择mysql的中间件来完成,使用专业的工具来做专业的事情,这也是为什么会有mysql中间件,而mysql router就是mysql官方开发的一款mysql中间件 尽管它不是最好的 但是足够让我们用来理解mysql中间件的运行方式了

  • 配置mysql router
[DEFAULT]
logging_folder = /var/log/mysqlrouter/
runtime_folder = /var/run/mysqlrouter
config_folder = /etc/mysqlrouter

[logger]
level = INFO

### 读写策略  写操作只允许主服务器
[routing:read_write]
bind_address           = 10.0.1.180
bind_port              = 9468
destinations           = 10.0.1.180
mode                   =  read-write
max_connections        = 65535
max_connect_errors     = 100
client_connect_timeout = 9

### 只读策略   读操作可以在主服务器和从服务器之间进行负载均衡方案
[routing:read_only]
bind_address           =  10.0.1.180
bind_port              =  9469
destinations           =  10.0.1.180,10.0.1.181
mode                   =  read-only
max_connections        = 65535
max_connect_errors     = 100
client_connect_timeout = 9

[keepalive]
interval = 60

详细的mysql-router配置 请自行查看官方文档 这里只做我需要的基本配置

如果在配置的过程中 发生了错误导致mysqlrouter进程没有启动 需要分析/var/log/mysqlrouter/mysqlrouter.log 来找出错误的原因

测试mysql router

配置了mysql router之后 我们所有的mysql服务器就相当于对客户端不可见了

根据上面的配置 我们得到了读写策略和只读策略的地址 分别如下

# 读写服务器
地址:10.0.1.180 
端口:9468
#  只读服务器
地址:10.0.1.181
端口:9468

创建一个对测试机可以链接的用户

mysql> CREATE USER 'crisen'@'10.0.1.189' IDENTIFIED BY '123456'; 
mysql> GRANT ALL ON *.* TO 'crisen'@'10.0.1.189';
mysql> flush privileges; ## 因为已经配置了主从同步 所以只需要在主服务器上创建就可以了  但是从服务器也上需要运行flush privileges命令来刷新权限

在宿主机上使用命令测试链接情况

  1. 写操作
mysql -h10.0.1.180  -ucrisen -P9468 -p123456 -e "select @@hostname;"
+------------+
| @@hostname |
+------------+
| ubuntu180  |
+------------+
  1. 读操作
mysql -h10.0.1.180  -ucrisen -P9469 -p123456 -e "select @@hostname;"
+------------+
| @@hostname |
+------------+
| ubuntu181  |
+------------+
mysql -h10.0.1.180  -ucrisen -P9469 -p123456 -e "select @@hostname;"
+------------+
| @@hostname |
+------------+
| ubuntu180  |
+------------+

写操作返回的是主服务器,如果是读操作,那么返回的服务器名称会自动的进行负载均衡方案,如果选择其中一个服务器down的话, 那么mysql router会自动的剔除这个操作

尽管主从复制可以提高数据库的负载,但是主从同步的这个过程中,数据的一致性是没有办法百分之百保证的,需要其他的解决方案,不过这是主从复制的缺点,并不是mysql-router的缺点

完全在linux下工作的感受

完全在linux下工作的感受

或许linux这个词语在很多的想象中,一定充满geek的样子,其实我想说,这其实只是你们想象中的样子,但是并不是linux的全部。时至2018年了,ubuntu桌面版已经非常强大了,而且在深度科技的努力下,很多日常用的软件,也都能在linux运行,尽管现在大部分的普通用户都转移到了移动端,但是对于pc用户来说,尤其是程序员这个群体,linux绝对是你非常好的帮手。

当你能够看到这篇文章的时候,那么我现在可以断定你至少对这个用户数量最庞大操作系统是非常感兴趣的,接下来我愿意讲一下我迁移到linux的过程,希望能够给到你们一些些的帮助

了解自身的需求

linux肯定是不适合所有人的,但是它非常的适合我。作为一个php后端程序员,和服务器打交道是没有办法避免的,而服务器基本上运行的都是linux操作系统,而且是纯命令行模式的,对于服务器来说,图形界面完全就是一种浪费。

那么对于我来说,我需要的操作系统应该是什么样的呢?

  • 首先我需要编程,我需要一个php的IDE
  • 我需要管理服务器,我需要顺手的终端
  • 我写程序的时候,有时候会需要听歌来防止被外界干扰,我需要一个听歌软件
  • 我会经常需要管理数据库,尽管我很熟悉mysql命令行,但是一个好用的图形化界面也能锦上添花
  • 我经常需要做很多的测试,而这些测试可能会损坏我的系统,那么我需要一个虚拟机软件
  • 我需要上网,我需要一个好用的浏览器
  • 我需要一个好用的输入法
  • 我喜欢markdown来写文档,所以我需要一个markdown编辑器
  • 有时候我需要调试接口,我需要一个好的接口调试工具
  • 或许我可能无法避免的接触到psd文件,我还需要一个可以操作图片的工具,就像photoshop那样
  • 除了编程之外,还有一些日常的琐碎事情,比如同事之间的沟通,我可能需要excel,word工具
  • 我没有办法避免的需要和其他同事沟通,我需要万恶的qq和微信
  • 我有时候需要画脑图,我需要一个脑图工具
  • 我不可避免的还需要画流程图,还需要一个流程图工具
  • 除了这些可见的程序以外,我可能还需要一些开发工具,比如版本控制,lnmap环境等等
  • 当然还有最重要的一点,我可能需要工具来访问stackoverflow来解决问题,这里需要一个被和谐的工具

首先我相信,我的这些需求,也绝对是大部分用户需要用的,而且我相信如果你用的windows或者mac操作系统,一般用的功能也都差不多。

在linux下应该如何满足自身的需求

我所选择的操作系统是ubuntu16.0.4,虽然它被戏称是基于“内部错误”构建的操作系统,或许它没有arch那么优雅,没有centos那么稳定,也没有openSUSE那么简约,但是它可以让我折腾少一点,至少对于两年前的我来说,它应该最易用的操作系统了。那么我怎样用它来迎合我这么的需求的呢

编程工具

虽然windows下有史上最强大的IDE-----“visual studio”,但是作为php程序员,我写的代码都是php,js,bash这些,史上最强IDE是无福消受了

但是我有phpstorm vscodevim

终端

ubunut下不用考虑终端的问题,ctrl+alt+t 直接就调出来了,极致体验,完美使用,尤其是在apt的强大包管理之下,更是丝滑的顺畅

听歌

这里要感谢"深度科技"和“网易云音乐”,linux下我的网易云音乐运行的非常的流畅

数据库管理工具

或许你觉得phpmyadmin配置很麻烦,mysqlworkbench很难用,命令行下运行又不太舒服,那你可以试试navicat for linux啊,尽管它是wine版的,但是一定可以满足你的需求

虚拟机

虚拟机vmware,virtualbox 本身就是支持linux版的,而且linux下的体验也非常的棒

浏览器

如果你对ie没有特别的感情的话,你可以试试firefox和google的浏览器啊

当然,如果你喜欢“某数字”浏览器的,抱歉 我不认识你

输入法

linux的的中文输入法,可能就没有什么什么太好的办法了,毕竟万恶的“某讯”,从不开发linux平台的软件,这里要感谢搜狗,虽然搜狗也是“某讯”旗下的,但是也改变不了腾讯万恶的事实,linux下的搜狗输入法,用起来感觉还行,除了翻页变成了"+""-"号,偶尔会抽风,其他都没有什么问题,而且编程我也几乎不使用中文,所以没什么太大的影响,而且ftix用起来也是不错的

markdown编辑器

如果你和我一样喜欢markdown语法的话,那么typora一定非常适合你,它可是可以支持windows,mac,linux三个平台的,感谢typora照顾到了我们这群linux用户

接口调试工具

虽然浏览器又很多这样的插件,但是仍然又强大的postman供你选择,linux的postman,你应该会非常喜欢的

图形图像处理

可能你的感觉是linux不太适合处理图形和图像,但是我想说这只是你的错觉,强大GIMP工具,一定可以给你不一样的体验

excel && word

你说你需要日常办公? 是的我有些时候也需要。开源,免费,没有任何捆绑的libreOffice你值得拥有,当然还有wps的软件,linux下用也是没有任何问题的

万恶的qq与微信

万恶的某讯太无耻了,qq和微信没有linux版本

但是这里我们有三个选择

  • 使用网页版
  • 使用手机,移动版用
  • 使用wine, 用老版本的qq 比如qq2012国际版(我用的就是这个,尽管有些抽风,凑合用了)

其实换句话说,没有qq和微信也是一件好事情,至少不用被太多繁琐的事情来打扰了

脑图

脑图又称思维导图,如果你喜欢脑图的话,不用担心xmind官方就提供了linux版

流程图工具

linux其实也有比较好用的流程图工具的,正如dia,它看起来就是那么的简约,毫不做作

其他服务类型的软件

  • 集成环境

如果你和我一样是个php程序员,那么你一定需要一个php的集成环境

如果你在windows下,那么你极有可能用的就是phpstudy和wanmp这两种

其实我真的很想说,这种集成环境其实真的并不适合你们,我们要做到的是对mysql apache nginx php这四个单独软件的掌控,集成起来会蒙蔽很多的细节,不利于成长

在linux,尽管也有集成环境给你选择,比如oneinstack,lanmp等等,但是如果用强大的apt工具,岂不是来的能加的痛快

sudo apt install nginx
sudo apt install mysql
sudo apt install php
  • composer

如果你用composer的话,那么你在windows下一定踩了非常多的坑,如果你在ubuntu下的话

sudo apt install composer

如此简单就可以拥抱composer

  • 版本控制

目前最流行的版本控制工具就是git了,如果你在windows下安装,还会附带一个git bash给你,而且用起来还不是特别好

但是在ubuntu下

sudo apt install git

没错,和composer一样,就是一条命令,然后调起终端就可以了

和谐工具

和谐工具我就不推荐了,但是我可以保证linux下用起来的感觉觉得更加的流畅

可能有些时候,有一些实在是只能windows运行的软件,比如万恶的“某讯”软件(X信开发者工具),那么我们还有非常好的解决方案,我们可以跑一个windows的虚拟机

我的windows虚拟机除了用来跑一下微信开发者工具做测试之外,就没有任何的用处了,万恶的“某讯”

为什么如此极力推荐linux

我如此推崇linux,并不是因为它可能显的高大上一点,而是真的可以为你的未来的道路点亮一盏启明灯。

linux有数不清的非常好用的软件,不同的软件相互组合,能够做到你甚至无法想象的任务。尽管它的学习曲线难度是有一些,但是你真的愿意掀开她的面纱,绝对受益无穷。

如果你和我一样是个程序员,那么你就无法避开服务器,而服务器一般都是linux操作系统,所以如果你的工作环境是linux,那么你一定可以更好的切换到服务器上工作。

如果你是个普通人,那么linux可以让你免受各种流氓软件的袭扰,包括但不限于"X度全家桶","数字全家桶",“企鹅全家桶”,从而提升你的使用体验。

如果你是一个爱学习的人,那么就更不应该错过linux了,使用linux可以让你明白更多的底层相关的知识,让你感受进程管理,文件管理,网络管理等等计算机内在的魅力。

服务器安全加强攻略(linux)

系统环境

  • cento7

故障现象

这几天同事找到我,说服务器好像被挂马了,让我去检查一下

ssh到服务器之后,输入lastb命令看了一下,出来出来一大堆的ip正在尝试破解服务器的密码

完全没有运维的服务器,是多么的脆弱,为了避免被对方用字典暴力破解了服务器

那么接下来就要对服务器的安全性进行加强了

解决过程

因为字典暴力破解都是猜用户名,然后用生成好的字典不断的对服务器进行尝试,然后获得shell权限

而且linux大多数服务器都有root用户,所以root用户的尝试次数必定是最多的,

为了增加对方的攻击成本,那么我们首先要做这样设置

  1. 创建普通用户

  2. 设置普通用户的sudoer权限

  3. 禁止root账户远程ssh登录

用普通用户来远程登录,并且sudo已经可以解决大多数问题了,实在需要root来执行某些任务的时候,再使用su root来切换到root执行,这样做的话,对方就需要猜测用户名,然后再猜测密码,攻击难度瞬间就提升了一大截

  • 创建普通用户并设置密码
useradd someuser && passwd someuser
  • 设置sudoer权限

打开/etc/sudoers

chmod u+w /etc/sudoers 
vim /etc/sudoers 

找到root ALL=(ALL) ALL 然后加上新创建的普通用户

root    ALL=(ALL)       ALL
someuser  ALL=(ALL)       ALL
  • 禁止root账户远程登录

打开ssh的配置文件 /etc/ssh/sshd_config

vim /etc/ssh/sshd_config  

找到 PermitRootLogin改成no,如果没有找到 那么添加一行

 PermitRootLogin no

接着重启sshd服务

/bin/systemctl restart sshd.service

如果不是centos服务器,使用的命令一般是service sshd restart

这样做就提高了很大的安全性了,但是这只是一个简单的隐藏而已,并不能真正的解决根本性的问题,只要给对方时间,猜测到账户和密码还是有可能的,为了一劳永逸,我们还需要把这些恶意的ip全都封掉,但是手动封肯定是不现实的,所以我们需要一个自动化的脚本,这个脚本的作用如下

检测10分钟内,尝试失败登录次数超过5次的ip,然后使用iptables把这些ip地址全都禁掉,然后把这个脚本设置为每十分钟执行一次 就可以自动的封禁这些ip了,至于这个脚本怎么写就很随意了,你可以用php python bash等任何一种脚本语言来实现这个过程,这里是我用bash写的一个简单的例子

#!/bin/bash

now=`date +'%H%M'`
start=`date +'%H%M' -d '-10min'`
lines=100000
iptables=/sbin/iptables
blacklist=./blacklist
limitnum=5
ipList=`lastb |   head -n ${lines} |  awk '{ gsub(/:/,"",$7); if($7>='${start}' && $7<='${now}') { tmpData[$3]++} } END{ for(i in tmpData){if(tmpData[i]>=7){print i}} }'`

if [ ! -f ${blacklist} ];then 
    echo ""  > ${blacklist}
fi

for ip in  ${ipList};do
    if [  `cat ${blacklist} | grep ${ip} | wc -l`  -eq 0 ];then
        echo ${ip} >> ${blacklist}
        ${iptables} -D INPUT -s  ${ip} -p tcp --dport 22 -j DROP
    fi
done

尾语

我发现很多公司基本都不注重linux服务器的安全性,我大概看了一下攻击我方服务器的大部分ip,基本上都是别人的肉鸡,而且都是自动化批量式的扫描。像这种扫描,一旦你的服务器被命中并且破解成功,就变成一台新的肉鸡了,然后就会继续去感染其他的机器,如此这样反复的感染下去,最后被感染的机器就越来越多,整个网络里都充满了无用的数据包。所以为了整个网络环境的安全性,我希望所有使用linux服务器的人,都应该掌握一点点基本的linux的防范,不要让自己珍爱的服务器变成了其他人手中的武器。

记一次innobackupex工具恢复数据库过程

innobackupex工具恢复数据库

今天正在午休的时候,同事突然给了一份dummy.tar的innobackupex备份数据,需要我恢复一下.因为是innobackupex全量备份,那么第一件事情自然就是准备虚拟机了.好在我平常就有镜像当前操作系统作为沙箱环境的习惯.接下来事情就简单了.

安装数据库

  • 操作系统环境(virtualbox):ubuntu16.0.4

首先安装mysql

sudo apt install mysql

接着安装innobackupex工具,innobackupex工具实际上是percona公司推出的一款数据库备份工具,它实际的名字其实是percona-xtrabackup,所以接下来要把这个工具下载下来

我的操作系统是ubuntu16.0.4,根据页面上对应的版本,选择对应的下载资源

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12/binary/debian/xenial/x86_64/Percona-XtraBackup-2.4.12-r170eb8c-xenial-x86_64-bundle.tar

解压

tar -xvf Percona-XtraBackup-2.4.12-r170eb8c-xenial-x86_64-bundle.tar

安装

sudo dpkg -i *.deb

修复依赖

sudo apt -f install

验证

which innobackupex

恢复数据

我的备份文件是dummy.tar,解压之后的格式如下,如果你的备份文件不包含下面的文件,说明你的备份文件不对

.
├── backup-my.cnf
├── ib_buffer_pool
├── ibdata1
├── mysql
├── performance_schema
├── sys
├── xtrabackup_checkpoints
├── xtrabackup_info
└── xtrabackup_logfile

我的压缩包一开始就是没有tar后缀的tar文件,结果就一直没办法备份下来,然后尝试性质的使用tar解压一下,才把目录给解压出来的

  • 恢复数据(恢复数据之前,必须要关闭数据库,并且当前用户需要有对数据库目录的权限)

使用apt安装的mysql,数据目录在/var/lib/mysql ,配置文件在/etc/mysql/my.cnf

关闭数据库

sudo service mysql stop

删除数据库原有的文件(删除之前,要确保你的数据库没有可用的数据,如果有可用的数据库,一定要先做备份,或者选择虚拟机来进行恢复工作)

sudo rm -rf /vat/lib/mysql/*

恢复数据

恢复数据有两个过程,首先是apply-log 然后才是cpoy-back

sudo innobackupex --defaults-file=/etc/mysql/my.cnf --user=root --password=123456 --use-memory=4G --apply-log /backup/mysql/data/dummy 
sudo innobackupex --defaults-file=/etc/mysql/my.cnf --user=root --password=123456 --copy-back /backup/mysql/data/dummy

恢复mysql权限(可能需要的操作如果权限不对,mysql将无法启动)

sudo own mysql:mysql -R /var/lib/mysql

重新启动数据库

sudo service mysql start

备份之后,数据库密码就不再是你原来的密码了,而是你备份的数据库的密码

记一次服务器优化

服务器环境

  • 双核心cpu 8G内存
  • 操作系统:centos6
  • web服务器: apache2.4
  • php版本: 5.6
  • mysql版本:5.5

起因

公司的网站在最近一段时间访问变的非常的缓慢,作为公司唯一略懂linux运维的人,这个任务毫无疑问的就落到了我的头上了,于是请求到了ssh权限之后,就开始了我的工作了。

问题分析

首先网站本身的访问量是不多的,猜测应该不是自然负载很高

其次服务器的代码和数据库并没有任何人动过

那么我唯一能想到的原因就是网站被ddos了,接下来验证一下猜想

解决过程

首先ssh到服务器,使用top命令查看一下当前服务器的负载情况,检测到httpd进程占用了cpu达到百分之百

这么就确定是被ddos了,接下来只要分析apache的日志,把恶意的ip封禁掉就可以了

  • 日志文件在/home/wwwlogs/access_apache.log

  • 日志格式如下

124.239.252.4 - - 2018-10-26 11:49:15 "OPTIONS * HTTP/1.0" 200 -

在awk处理的时候,以空格为分隔符,每一列分别对应$1,$2.....$9...

如果你的apache日志和我的不一样 那么通过打开http.conf修改LogFormat如下,然后重启httpd服务

LogFormat "%h %l %u %{%Y-%m-%d %H:%M:%S}t \"%r\" %>s %b" common

使用tail+awk组合命令对日志文件进行分析

tail -n 10000 /home/wwwlogs/access_apache.log  | awk '{A[$1]++;}END{for (a in A) print A[a] "  "a}' | sort -n

通过这个列举出最近10000次内访问的ip地址, 并且能够看到ip地址数量

发现ip为124.239.252.4的机器在10000次内居然有2000次的访问量,那么很容易得出这不是人类所为,接下来只要利用iptable强大的功能,把这个ip给封掉就可以了

iptables -I INPUT -s 124.239.252.4 -p tcp --dport 80 -j DROP

如果要封禁124.239.252的ip段,ip应该填写(124.239.252.0/24),24表示掩码长度

封完之后还得记得把封掉的ip记录一下,方便误杀恢复

最后再使用top命令看一下cpu负载,发现cpu占用只有20%不到,那么便大功告成了

尽管可能又漏网之鱼,但影响不大就可以了,搞定之后,就可以愉快的去做其他的事情了.