分类 技术相关 下的文章

Memcache这玩意虽然也是用于php连接memcached服务的,但是十分古老了,而且貌似也不维护了。

如果需要从Memcache迁移到Memcached,就会涉及到兼容性的问题——这里的兼容性发生在线上升级的时候,一部分机器升级了Memcached,然而旧的机器缓存还是用Memcache写入的,Memcached读出来就会产生问题,导致升级过程中服务处于几乎不可用的状态。

问题1

Memcached默认会对超过一定长度的数据进行压缩,而Memcache是没有压缩的,因此调用Memcached的写入时,需要取消压缩:

$memcached->setOption(Memcached::OPT_COMPRESSION, false);

问题2

Memcached和Memcache在有多台memcached服务时,使用的默认散列算法不同。Memcache用的是crc32。因此需要把Memcached的散列算法也设置为crc32

$memcached->setOption(Memcached::OPT_HASH, Memcached::HASH_CRC);

问题3

通过Memcache写入memcached服务中的数据被Memcached读出来会被错误解读,反之亦然

这是由于Memcache写入的时候,设置在memcached服务中的flag无论如何都是0,而如果用Memcached写入(默认方式),则可能为0(string)、1(int)、3(对象)、4(数组)等等。这是因为Memcache是先做序列化再写入的,读取后也会默认做一次反序列化。因此在调用Memcached::set的时候,需要给被存入缓存的数据做一次序列化变成string,这样flag就一定是0,读写就和Memcache一致了。

// 写入
$memcached->set($key, serialize($value), $expire);
// 读取
$raw = $memcached->get($key);
$value = unserialize($raw);

GitHub

依赖

php版本7.x,已安装Memcached扩展,服务器上也已经部署Memcached服务。

使用方法

如果你的域名已备案(未经测试)

  1. 注册一个微信公众号(账号主体不可以是个人,否则微信的JS API无法使用)

    1. 设置公众号JS接口安全域名为你网站的域名(公众号设置-功能设置-JS接口安全域名)
    2. 开启微信JS API的分享功能(开发-接口权限,网页服务-分享接口)
  2. 安装插件并进行配置。

如果你的域名没有备案

可以通过测试公众号:

https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

实现此功能。限制就是,只有关注了你的测试公众号的微信账号,才能分享带缩略图和描述的链接,别人分享还是普通的链接。

测试公众号中也需要填写js接口安全域名。

- 阅读剩余部分 -

有如下需求:

我有一个域名 huangfeiqiao.com,我想在上面搭几个web应用,分别是foo、bar、baz。

一种办法就是在nginx的document root目录中建立foo、bar、baz目录,访问方式就是huangfeiqiao.com/foo、huangfeiqiao.com/bar等等。但这样有几个缺点——

  1. 某些web应用可能本身就不支持非根目录的方式访问,导致不可用
  2. 因为各个应用可能需要进行location的特殊配置,而这些应用不在根路径的时候,location配置可能有所不同,更加复杂
  3. 不够酷

需要让foo、bar、baz都拥有自己的子域名(foo.huangfeiqiao.com、bar.huangfeiqiao.com等等),可以这么做:

  1. 在域名服务商那里,加一个CNAME记录,把需要配置的子域名指向根域对应的主机名即可。
  2. 然后这么写nginx配置:
server {
    listen 80;
    listen 443 ssl;
    server_name  huangfeiqiao.com;
    # blah blah...
    # 设置子域名目录
    set $doc "";
    if ($host ~ ^(\w+)\.huangfeiqiao\.com$) {
        set $doc $1;
    }
    # www的话就是根目录
    if ($host = "www.huangfeiqiao.com") {
        set $doc "";
    }
    # 设置此时域名对应的root
    root /path/to/www/$doc;
    index index.html index.htm index.php;

    # 日志配置
    access_log  logs/$host.access.log  main;
    error_log  logs/error.log;
}

搞定。

这样做的好处就是,之后要加个子域名,只要在www目录中新建一个子目录,取子域名作为目录名,然后在域名服务商新增一条字域名的CNAME记录就搞定了,非常方便。

站点运行在nginx服务,然而我并不想使用root来跑这个服务,因此也没法使用80端口。于是想着是否可以使用iptables进行端口转发,将80端口的数据转发到nginx服务的端口8888。

在搜了一堆资料后,有了如下方法

#!/bin/bash
# nat表,PREROUTING链增加转发规则
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8888
# mangle表,PREROUTING链给发向8888的包做个标记
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 8888 -j MARK --set-mark 1
# filter表,INPUT链,首先允许所有本地接口的数据包
iptables -t filter -I INPUT -i lo -j ACCEPT
# 然后拒绝所有被标记了1的包
iptables -t filter -A INPUT -m mark --mark 1 -j REJECT