DiscuzQ 在 MySQL 5.6 安装 Specified key was too long; max key length is 767 bytes

DiscuzQ吃瓜第一个坑,MySQL 5.6 下安装的时候出现索引长度 安装出错:

 SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long;   
 max key length is 767 bytes   
 (SQL: alter table `group_permission` add primary key `group_permission_group_id_permission_primary`(`group_id`, `permission`))

那么在 MySQL 5.6 下要有没有办法安装呢? 其实是有的,如果熟悉 Laravel 的,都知道 Laravel 5.x 开始,在 MySQL 5.6 下也有这个问题,解决方式在AppServiceProvider::boot() 里面加上 Schema::defaultStringLength(191); 就可以解决问题了。

DiscuzQ 也是基于 Laravel 的,那么搞起。 结果发现,不行报错了:Call to a member function connection() on null ,看了是 DiscuzQ 没有完全使用 Laravel 的机制啊。 继续去跟安装方法,找到:app/Install/Controller/InstallController.php 文件,里面有一个函数, installDatabase 先进行数据库初始化和连接。后面才行执行数据表迁移。

那么可以在这个位置加上defaultStringLength,修改方式如下:

![Fu6o5ZFfM3BElCwXLITuTHgg4D2...

[阅读更多 →]

  • PHP 开发者学 Golang 之 URL 编码 (Urlencode)、解编码 (Urldecode)

    作为一个PHP开发者,在PHP语言中,我们对URL进行编码和解编码处理,可以使用 urlencode()urldecode() 函数。

    在 Golang 中有 net/url 包是用来专门处理 URL 的, net/url 包有完整的URL解析函数,编码函数,解编码函数。

    URL 解析

    解析 URL 可以使用 url.Parse() 函数。这个函数功能类似于 PHP 下的 parse_url() 函数。

    import (
        "fmt"
        "github.com/liudng/godump"
        "net/url"
    )
    urlStr := "https://cong5.net/post/golang?name=张三&age=20&sex=1"
    parseUrl,_ := url.Parse(urlStr)

    URL 解析后,我们来看一下返回的数据结构:

    (*url.URL)
        (url.URL)
            Scheme(string) "https"
            Opaque(string) ""
            User(*url.Userinfo)
              User(string) ""
            Host(string) "www.example.com"
            Path(string) "/index.php"
            RawPath(string) ""
            ForceQuery(bool) false
            RawQuery(string) "name=张三&age=20&sex=1"
            Fragment(string) ""

    要获取里面的某个值,可以这样直接获取:

    
    fmt.Println("Scheme:" + pars...

    [阅读更多 →]

    PHP 开发者学 Golang 之基本结构

    PHP 是一门弱类型的语言,所以 PHP 开发者的我们刚刚接触强类型的语言是有点蛋疼的。 在写普通程序的时候,弱类型挺方便的。但是在设计金钱相关的程序,强类型语言往往更安全。

    今天我们就来学习一下 Golang 的基本结构、基本数据类型。 每一门语言都有其关键字和预定义标识符。Golang 语言也不例外。

    Go 语言有25 个关键字或保留字,有 36 个预定义标识符。要记熟这些关键字和标识符。

    关键字或保留字

    break
    default
    func
    interface
    select
    
    case
    defer
    go
    map
    struct
    
    chan
    else
    goto
    package
    switch
    
    const
    fallthrough
    if
    range
    type
    
    continue
    for
    import
    return
    var

    预定义标识符

    append
    bool
    byte
    cap
    close
    complex
    complex64
    complex128
    uint16
    
    copy
    false
    float32
    float64
    imag
    int
    int8
    int16
    uint32
    
    int...

    [阅读更多 →]

    Redis 高级特性 Pipeline (管道) 使用和基本测试

    都说 Pipeline 有很大好处,但是能量是守恒的,好坏也是相对的。 所以我们主要来测试看看 Pipeline 的利弊。 带着几个问题我们来进行基本的测试。

    1. Pipeline 对命令数量是否有限制?
    2. Pipeline 打包执行多少命令合适?
    3. Pipeline 批量执行的时候,是否对Redis进行了锁定,导致其他应用无法再进行读写?

    Redis 常规使用方式

    我们都知道Redis 是单线程的,那么在常规使用情况下,我们使用 Redis ,如下代码执行是什么流程呢?

    $key1 = "abc1";
    $key2 = "abc2";
    $key3 = "abc3";
    $redisObj->set($key1, 1);
    $redisObj->set($key2, 2);
    $redisObj->set($key3, 3);

    Redis 的执行方式是逐条命令: 发送命令->执行->返回执行结果。

    如图:

    什么是 pipeline 呢?

    知道了常规的使用方式,那么我们再来看看 pipeline 模式,pipeline 模式则是将执行的命令写入到缓冲中,最后由exec命令一次性发送给redis执行返回。

    我们以灌一个list来进行测试,以20000条list数据为例,来对比一下常规模式的的写入和 pipeline 模式的写入。

    Redis pipeline 的执行方式: 打包开始->缓存->打包结束->发送->执行->返回执行结果。

    如图:

    ![](https://imgs.cong5.net/2018-12-18/15451266144880.jp...

    [阅读更多 →]

    记一个开启 ssl_session_tickets 导致的 SSL 证书冲突的问题

    很久不写东西了,自己都感觉自己太懒了,有深深的罪恶感了。 今天刚刚好遇到一个 Nginx 的问题,就硬逼着自己一定要写点什么记录一下。

    今天在突然发现自己的博客打不开了,提示很奇怪,提示内容是 此网站无法提供安全连接 . 回想了一下这两样的的操作,就是昨晚给服务器加了一个 https 的站点。

    假设1:SSL 证书过期了

    刚刚开始以为是 SSL 证书问题,看了一下证书的到期,也还有几天就到期了。脆重新去签发一个证书试试,但是重新签发后,发现问题依旧。

    再开 B 站点,都是正常的。唯独博客这个站点 A 有问题。

    假设2:SSL 证书冲突

    那么应该就是配置文件的问题了,首先想到的是是 SSL 证书冲突。

    一般来说一个 IP 只能支持一个 SSL 证书,但是在 Nginx 我们可以通过开启 TLS SNI support 来让 Nginx 支持多SSL证书。

    
    xxxx@xxxxxxx> /usr/local/nginx/sbin/nginx -V
    nginx version: nginx/1.12.2
    built with OpenSSL 1.0.1f 6 Jan 2014
    TLS SNI support enabled
    configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-ipv6 --wit...

    [阅读更多 →]

  • ERP 系统优化之客户信息、联系人信息缓存之 DB 解决方案

    昨天我们说了如何把 13.9+ 万的客户数据导入 Redis 以及客户联系人的数据导入Redis 服务器去。

    今天我们再来说说程序里面如何优化,做到数据在查询的时候首先从 Redis 里面取数据,当 Redis 没有数据的时候再从 MySQL 里面取数据,并缓存。

    数据的增删改,这个我们来写一套 DB 的解决方案,在数据进行 MySQL 增删改操作的时候,同时对 Redis 进行增删操作。

    一套同时操作 MySQL 和 Redis 的解决方案

    关于同时操作操作 MySQL 和 Redis 的方案有很多种,可以按需选择,可选的方案包括但是不限于以下的思路:

    我们可以全新开发一套 ORM ,这套ORM包含了操作 MySQL 和 Redis 的CURD同步操作。 利用系统现有的 DB 操作类进行二次封装操作方法,在操作方法里面同时进行操作 MySQL 和 Redis 的 CURD 的同步操作。 如果系统本身使用了开源框架来开发的,或者本身已经包含了 ORM 的,那么直接使用现有系统的 ORM 进行二次封装,重写 CURD 等方法,让其支持 MySQL 和 Redis 同步操作。 由于我们的ERP系统使用的是ThinkPHP框架来开发的,这里我们可以使用ThinkPHP自带的ORM来进行二次封装。

    首先新建客户信息的数据模型,ClientModel.class.php ,然后在模型里面我们重写 CURD 方法。

    缓存处理类

    
    ...

    [阅读更多 →]

  • ERP 系统优化之客户信息、联系人信息缓存之把数据放入 Redis 缓存

    最近写的这些文章都是对在职的时候的一些经验的总结。

    说到内存缓存我想很多人肯定会想想到 Redis 和 Memcache 这两个内存数据库。Redis 和 Memcache 的共同之处都是将数据存放在内存中,都支持一主多从,都支持过时设置。

    不同之处在于 Memcache 除了k/v类型的数据外还支持缓存其他东西,如图片等。 Redis 不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等更丰富数据结构的存储。 Memcache 挂了后数据会丢失,而Redis则可以通过aof恢复数据(当然,这个恢复是要点时间的)。

    两者的使用场景也一般不太一样,Redis 出来作为 NoSQL 数据库使用外,还能用做消息队列、数据堆栈和数据缓存等。 Memcached 适合于缓存 SQL 语句、数据集、用户临时性数据、延迟查询数据和session等。

    为什么要做缓存优化?

    因为每天早上的8:30 ~ 11:00 下午 2:00 ~ 4:00是员工使用ERP的高峰期,这时候的数据库的读写量很大,然后给 MySQL 就开始很吃力。

    这里从数据的稳定性和数据类型的支持程度来看,我们选择使用 Redis ,因为我们需要使用了计数器,队列等功能。

    既然是优化,那么我们首先从读写最频繁的数据表开始进行做优化,当前ERP里面的 客户信息(xx_client) 表和 客户联系人(xx_client_contact) 信息表,这两张表的读写是最频繁的。

    所以经过衡量,我们觉得把这两张表的信息放到 Redis 里面去。 数据在查询的时候首先从 Redis 里面取数据,当 Redis 没有数据的时候再从 MySQL 里面取数据。 数据的增删改,这个我们维护一套 DB 的解决方案,在数据进行 MySQL 增删改操作的时候,同时对 Redis 进行增删操作。

    下...

    [阅读更多 →]

    使用 PHP SWOOLE 定时同步 MySQL 数据

    南宁公司和几个分公司之间都使用了呼叫系统,然后现在需要做一个呼叫通话数据分析,由于分公司的呼叫服务器是在内网,通过技术手段映射出来,分公司到南宁之间的网络不稳定,所以需要把分公司的通话数据同步到南宁。

    本身最简单的方法就是直接配置 MySQL 的主从同步就可以同步数据到南宁来了。但是销售呼叫系统那边的公司不给 MySQL 权限我们。 所以这个方法只能放弃了。

    于是我们干脆的想,使用PHP来实现定时一个简易的PHP定时同步工具,然后 PHP 进程常驻后台运行,所以首先就先到了一个 PHP 组件:SWOOLE ,经过讨论,分公司的每天半天生成的数据量最大在5000条左右,所以这个方案是可行,就这样干。

    我们使用 PHP SWOOLE 做一个异步的定时任务系统。

    本身 MySQL 数据库的主从同步是通过解析Master库中的 binary-log 来进行同步数据到从库的。然而我们使用PHP来同步数据的时候,那么只能从master库分批查询数据,然后插入到南宁的slave库来了。

    这里我们使用的框架是 ThinkPHP 3.2.

    首先安装PHP扩展: SWOOLE,因为没有使用到特别的功能,所以这里我们使用pecl来快速安装:

    pecl install swoole

    安装完成后在 php.ini 里面加入 extension="swoole.so" 安装完成后,我们使用 phpinfo() 来检查是否成功了.

    安装成功了,我们就来写业务.

    服务端

    1、首先启动一个后台的服务端,监听端口9501

    
    public function index()
    {
       $serv = new \...

    [阅读更多 →]

    Omnibus-GitLab 配置 PostgreSQL 开启远程访问

    以前我安装Gitlab是使用源码安装的方式来安装的,这种方式的好处是可以高度自定义安装程序和指定安装位置。缺点是Golang、Ruby、Git 1.8+、Nodejs都需要编译安装,太麻烦了。

    现在家里面搞了台机器做内部服务器使用,想偷懒了。于是就开始试试 Omnibus-GitLab 这个一键安装包。

    但是Omnibus-GitLab 自带了 PostgreSQL 作为缺省的内部数据存储,比如用户信息, 源码仓库信息等。

    平时使用最多的是MySQL数据库,其次是MongoDB,或者SQL Server数据库,但是对PostgreSQL这个数据库却很少接触,只能去找Google大叔了。

    这里记录一下过程。

    PostgreSQL默认情况下,远程访问不能成功,如果需要允许远程访问,网站普遍是修改2个配置文件。

    这里为了安全,我们使用的是Password/Md5 Authentications的认证方式

    给 Gitlab 用户加上密码

    默认缺省情况下, Gitlab 用户使用的是 Peer Authentication , 这意味着客户端只能以 PostgreSQL 所在主机上的Linux系统账号访问数据库, 无法远程访问。

    1、设置PostgreSQL数据库用户 gitlab 的密码:

    $ su  - gitlab-psql #切换到gitlab-psql用户
    $ psql gitlabhq_production #连接gitlabhq_production数据库
    $ \password gitlab #修改密码,然后输入两次密码,回车
    $ \q #退出PostgreSQL

    2、配置 Gitlab 使用刚刚设置的密码连接数据库,在/etc/gitlab/gitlab.rb 中搜索# GitLab database settin...

    [阅读更多 →]

    ERP 一键呼叫系统开发

    简介

    公司购买了一整套呼叫系统的设备,然后分别部署到了南宁公司和各个下级市的分公司,然后要求这套呼叫设备系统需要能接入ERP,可以方便的从ERP的点击客户联系电话或者输入电话号码就可以通过网页快速呼叫出去。

    所以今天来总结一下呼叫系统开发实现的一些小细节。 (因为项目性质问题,这里代码里面的用户名和密码均修改为演示的)

    系统分析

    本身每套呼叫设备上都提供有一个C语言写的接口程序,对外提供WebService服务。

    那么呼叫系统在进行一键呼出的时候,可以通过调用WebService服务来实现跟电话设备的交互。

    因为南宁公司和4个下级市的分公司都分别处于不同的异地网络,所以每个公司都有一套呼叫的网关设备和服务器。

    那么相当于是5套呼叫设备了,每套都在不同的地方,但是ERP却是统一使用一套ERP,所以存在一个ERP如何调用到分公司内网内的呼叫设备的问题?

    关于这个的,我的解决方法是把呼叫模块独立成为一个服务程序,然后分别部署到各个公司的内部的一台服务器去,然后ERP的在线呼叫和呼叫弹屏的功能调用全部在走前端,然后走内网。

    还是存在一个问题,就是WebService接口验证呢?怎么知道当前调用接口的员工是谁呢?接口验证的时候需要传递工号,密码,分机号,等信息过去,明文肯定不行了的?

    那么就可以选择把员工的呼叫系统的信息进行使用公钥进行RSA加密,然后把加密后的字符串当做参数传递过去,在服务端再通过私钥进行RSA解密获取员工信息。

    只是这样如何保证部署在分公司的服务的可用性呢? Shell定时检测,如果服务不可用,则发送短信提醒。

    通话数据分析的需求也是包括南宁公司和下级市分公司,前面提到了,每个公司都有一台服务器保存通话记录,那么通话数据在四个分公司就是属于异地MySQL数据库了,从南宁公司远程连接到分公司内网的数据库这个稳定性无法保证这个问...

    [阅读更多 →]

    GitLab 迁移服务器后 SSH KEY 无效的问题

    前段时间在给公司的gitlab迁移服务器,过程也很简单,备份数据库,打包程序文件,打包启动项文件到新的服务器。 在新的服务器启动gitlab,可以正常启动,但是却遇到了一个奇葩的问题: git push,git pull 的时候,却提示验证失败。无法识别SSH KEY,尝试过删除了,然后重新添加SSH KEY也不行。 最后经过多层次的Google,才找到以下资料:

    public-key-authentication-fails-only-when-sshd-is-daemon 一次由SELinux引起的ssh公钥认证失败问题

    得到的原因是:是因为.ssh目录没有ssh_home_t标签!!

    既然知道了原因,那么接近也比较简单了。 通过下面命令重置:

    [root@249 ~]# restorecon -r -vv /root/.ssh

    [root@249 ~]# restorecon -r -vv .ssh restorecon reset /root/.ssh context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:ssh_home_t:s0 restorecon reset /root/.ssh/id_rsa context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:ssh_home_t:s0 restorecon reset /root/.ssh/known_hosts context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:ssh_home_t:s0 restorecon reset /root/....

    [阅读更多 →]

    MySQL 主从同步部分数据表

    今天来讲讲MySQL主从同步的配置和只同步我们指定的数据表。

    惯例,来说说缘由。 因为天津总公司那边需要读取我们南宁公司的ERP的营收数据。 然后我们南宁这边的ERP数据库服务器为了安全是只能内网访问的。 So.这样来解决:

    Tips: 以下ERP数据库所在的服务器为主服务器A,外网可访问的从服务器为B

    一、我们找了另外一台内部的服务器B,开启了外网访问,让天津可以访问到我们的这台服务器。

    二、然后需要配置MySQL主从同步,让ERP数据库的特定的几个数据表同步到可以外网访问的服务器B去。

    三、开启外网访问,完工。

    本篇完~~,哈哈哈。

    不扯淡了,开工~

    暂定:

    主服务器IP:192.168.1.100 从服务器IP:192.168.1.101

    Tips

    在配置MySQL主从同步的时候需要保证一下几点:

    1. 在服务器上必须开启二进制日志
    2. 主服务器的server-id只能是:server-id=1
    3. 每一台从服务器都需要配具有唯一性的server-id
    4. 开始复制进程之前,需要现在主服务器上记录二进制文件,以及最新位置Position
    5. 创建一个从服务器链接主服务器的帐号。(推荐限制一下可访问IP,这样更安全)

    配置Master服务器(主服务器)

    1、更改主服务器MySQL配置文件,/etc/my.cnf,检查二进制日志log-bin是否开启了,把server-id设置为1

    [mysqld]
    log-bin=mysql-bin
    binlog_format=mixed
    server-id   = 1

    2、创建一个从服务器链接主服务器的帐号 (1)、在命令行下登录mysql:

    # mysql -uroot -p

    (2)、首先创建一个名为:slav...

    [阅读更多 →]

    遇到了 Vuejs 使用 Sortable 进行排序数据更新了 Dom 没更新

    最近在使用 Vuejs 来改写网站博客后台,开始实现前后端完全分离的设计。 后台有一个自定义导航菜单的功能,于是 Sortable 来进行导航菜单拖动排序。 但是却遇到了一个很蛋疼的问题,就是数据更新了,但是 Dom没有更新,或者 Dom 更新出来位置始终是不对的,真是百思不得其姐~~~

    代码如下:

    
                            ☰ {{ item.name }}
                             x 
    
    
    import Sortable from 'sortablejs';
        export default{
            data(){
                return {
                    navigations: [
                        {name: 'google', url: 'https://www.google.com.hk/'},
                        {name: 'baidu', url: 'https://www.baidu.com/'},
                        {name: '163', url: 'https://www.163.com/'},
                        {name: 'taobao', url: 'https://www.taobao.com/'},
                ...

    [阅读更多 →]

    解决树莓派从 USB 硬盘启动,同时挂载多块硬盘无法启动的问题

    为什么要从硬盘启动呢?主要的原因是因为如果树莓派有时突然断电,如果内存卡还在写入的话,就会导致文件损坏,然后系统无法启动了。另外还有一点就是,我嫌弃内存卡的读写速度还是太慢了。

    所以作为一个喜欢折腾的人,就肯定要折腾一番了,同时这几天买的4T红盘到了,也该把树莓派做成一个NAS来使用了。

    好了,我们进入正题,树莓派从USB硬盘启动,那么我们还是脱离不了内存卡,因为树莓派通电后,首先读取的是内存卡的引导分区,然后修改内存卡的启动分区cmdline.txt 文件,让其从硬盘启动。

    步骤1,格式化硬盘,同步系统到硬盘:

    准备一快硬盘,使用parted进行分区,分区表选择GPT,为了更好的支持UUID挂载,为什么不直接使用:/dev/sda1 这样的形式挂载硬盘?而要使用UUID的方式呢??

    主要考虑到如果引导时指定的是sda1,显然如果有新的存储设备连接到树莓派,开机启动时很可能因为sda被占用而造成不能开机问题,也是本文的重要的中心。

    分区的过程略过,可以Google到好多的教程...

    最后把分区格式化成ext4的文件系统:

    //格式化分区
    sudo mke2fs -t ext4 -L rootfs /dev/sda1
    //挂载分区
    mount -t ext4 /dev/sda1 /mnt
    //把内存卡里面的/目录下的全部文件拷贝到移动硬盘的启动分区
    sudo rsync -axv / /mnt

    步骤2,修改树莓派引导分区:

    把内存卡拔下来,使用读卡器接入到一台电脑,打开/boot分区下的:/boot/cmdline.txt 文件,进行修改。

    原来为:

    
    dwc_otg.lpm_enable=0 console=tty1 console=ttyAMA0,115200 root=/dev/...

    [阅读更多 →]

    自己 DIY 一个树莓派的架子

    最近在折腾把树莓派变成NAS,然后树莓派虽然体积小,但是如果要使用起来需要外接很多的东西,于是就很多线乱七八糟的,外接的设备也很多,设备总共有:

    • 树莓派主板 x1
    • 一块2.5英寸的硬盘 x1
    • 一个USB HUB x1
    • 一个TP Link WR802N 的迷你路由 x1
    • 4T红盘+底座 x1

    这堆东西混在一起,感觉很乱,很占地方。 于是想在淘宝找找有没有合适的小机箱之类的东西,但是找来找去,都很不合意。

    最后在想我能不能自己DIY一个呢?完全定制,舒适、美观、心情舒畅……

    哈哈,说做就做,首先我们选材,我想到的适合的材料有5种:

    材料 优点 缺点 推荐
    木板 易于加工 便宜的木板不好看,好看的木板不好加工,成本太贵 ❆❆❆❆
    钢板(厚度0.5cm) 耐高温,硬度大,稳定 不好加工,成本太高 ❆❆❆
    亚克力 相对钢板好加工,价格也适中 比较容易被刮花,不美观 ❆❆❆❆❆

    好吧,这样一对比,最后我还是选择了亚克力这种材质。最后剩下来的就是找万能的某宝了,去定制,去某宝了解了,商家是机床直接根据CAD图加工,好吧,就做一个CAD图:

    树莓派架子设计图

    物料

    板子有了,然后我们还需要一些螺丝和螺母来固定,这些东西还是在万能的某宝解决,总共的物料如下: 混合杂类钉子/螺母

    file...

    [阅读更多 →]

    1 / 2