centos 使用docker搭建Gearman任务分发系统 ,Gearman的安装和使用

第一步,centos 安装 docker,拉取docker centos 镜像(此处不赘述)

https://docs.docker.com/install/linux/docker-ce/centos/

docker -v

docker ps  (查看docker的容器状态)

docker pull centos(docker安装ubuntu最新镜像)
docker images (查看本地所有镜像)

 

[root@izwz9c4rb2kbs0ggxd67hiz ~]# docker run -d -it –name=gearman-container centos:latest /bin/bash(name前面双横线)

docker ps

docker exec -it f49a2392164e /bin/bash

f49a2392164e(CONTAINER ID)

 

以centos运行docker容器

第二步,搭建Gearman任务分发系统

yum update

[root@f49a2392164e /]# yum install gearmand
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
* base: mirrors.163.com
* extras: mirrors.163.com
* updates: mirrors.cn99.com
No package gearmand available.
Error: Nothing to do

yum没有找到对应依赖包,更新epel第三方软件库,运行命令:
yum install -y epel-release

更新完epel第三方软件库后,再次尝试使用yum命令安装对应的软件包

yum install gearmand

remi — linux下比较好用的安装源

yum install wget

在centOS下下载源

su
cd /etc/yum.repos.d
wget http://rpms.famillecollet.com/enterprise/remi.repo

安装php扩展

yum install –enablerepo=remi –enablerepo=remi-php56 php-pecl-gearman

或升级:
yum –enablerepo=remi-php55,remi update php*

查看扩展是否安装成功

php -m | grep gearman

 

worker.php

<?php
    $worker= new GearmanWorker();
    $worker->addServer("127.0.0.1", 4730);  
    $worker->addFunction("title", "title_function");
    while ($worker->work());

    function title_function($job){
        return "你请求的数据:" . $job->workload() . " 请求时间:" . date('Y-m-d H:i:s');
        //return ucwords(strtolower($job->workload()));
    }
?>

 

client.php

 

<?php
    $client= new GearmanClient();
    $client->addServer("127.0.0.1", 4730);
    print $client->do("title", json_encode(
        [
            'username'=>'jack',
            'email'=>'jack@foxmail.com',
        ]
    ));
    print "\n";
?>

 

测试:

启动服务

$ sudo gearmand -d

启动worker

$ php worker.php &
[1] 15135

启动client

$ php client.php 
你请求的数据:{"username":"jack","email":"jack@foxmail.com"} 请求时间:2017-07-10 23:25:30

参考:
https://segmentfault.com/a/1190000000494087
https://www.ibm.com/developerworks/cn/opensource/os-php-gearman/
http://gearman.org/getting-started/#client
http://php.net/manual/zh/book.gearman.php

https://www.jianshu.com/p/c7a55dee5796

php unserialize 返回false的解决方法

php unserialize 返回false的解决方法

php 提供serialize(序列化) 与unserialize(反序列化)方法。

使用serialize序列化后,再使用unserialize反序列化就可以获取原来的数据。


<?php
$arr = array(
'name' => 'fdipzone',
'gender' => 'male'
);

$str = serialize($arr); //序列化
echo 'serialize str:'.$str."\r\n\r\n";

$content = unserialize($str); // 反序列化
echo "unserialize str:\r\n";
var_dump($content);

 

输出:

serialize str:a:2:{s:4:”name”;s:8:”fdipzone”;s:6:”gender”;s:4:”male”;}

unserialize str:
array(2) {
[“name”]=>
string(8) “fdipzone”
[“gender”]=>
string(4) “male”
}

但下面这个例子反序列化会返回false

 


<?php
$str = 'a:9:{s:4:"time";i:1405306402;s:4:"name";s:6:"新晨";s:5:"url";s:1:"-";s:4:"word";s:1:"-";s:5:"rpage";s:29:"http://www.baidu.com/test.html";s:5:"cpage";s:1:"-";s:2:"ip";s:15:"117.151.180.150";s:7:"ip_city";s:31:"中国北京市 北京市移动";s:4:"miao";s:1:"5";}';
var_dump(unserialize($str)); // bool(false)
?>

检查序列化后的字符串,发现出问题是在两处地方
s:5:”url”

s:29:”http://www.baidu.com/test.html”

这两处应为

s:3:”url”

s:30:”http://www.baidu.com/test.html”

出现这种问题的原因是序列化数据时的编码与反序列化时的编码不一致导致,例如数据库是latin1和UTF-8字符长度不一样。

另外有可能出问题的还有单双引号,ascii字符”\0″被解析为 ‘\0’,\0在C中是字符串的结束符等于chr(0),错误解析后算了2个字符。

\r在计算长度时也会出问题。

解决方法如下:


// utf8
function mb_unserialize($serial_str) {
$serial_str= preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
$serial_str= str_replace("\r", "", $serial_str);
return unserialize($serial_str);
}

// ascii
function asc_unserialize($serial_str) {
$serial_str = preg_replace('!s:(\d+):"(.*?)";!se', '"s:".strlen("$2").":\"$2\";"', $serial_str );
$serial_str= str_replace("\r", "", $serial_str);
return unserialize($serial_str);
}

&nbsp;

echo '<meta http-equiv="content-type" content="text/html; charset=utf-8">';
 
// utf8
function mb_unserialize($serial_str) {
 $serial_str= preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
 $serial_str= str_replace("\r", "", $serial_str);
 return unserialize($serial_str);
}
 
$str = 'a:9:{s:4:"time";i:1405306402;s:4:"name";s:6:"新晨";s:5:"url";s:1:"-";s:4:"word";s:1:"-";s:5:"rpage";s:29:"http://www.baidu.com/test.html";s:5:"cpage";s:1:"-";s:2:"ip";s:15:"117.151.180.150";s:7:"ip_city";s:31:"中国北京市 北京市移动";s:4:"miao";s:1:"5";}';
 
var_dump(unserialize($str)); // false
 
var_dump(mb_unserialize($str)); // 正确

使用处理过单双引号,过滤\r的mb_unserialize方法就能成功反序列化了。
使用unserialize
bool(false)

使用mb_unserialize
array(9) {
 ["time"]=>
 int(1405306402)
 ["name"]=>
 string(6) "新晨"
 ["url"]=>
 string(1) "-"
 ["word"]=>
 string(1) "-"
 ["rpage"]=>
 string(30) "http://www.baidu.com/test.html"
 ["cpage"]=>
 string(1) "-"
 ["ip"]=>
 string(15) "117.151.180.150"
 ["ip_city"]=>
 string(31) "中国北京市 北京市移动"
 ["miao"]=>
 string(1) "5"
}

PHP函数能解码德语 实体符号 转成 实际字符(ä,ö,ë)


Schlankheitspillen Fat Burner | Abnehmen BMI Gewichts-Kontrolle l Fettverbrenner Gewichtabnahme| Appetitz&amp;uuml;gler - Unterdr&amp;uuml;ckung Fetts&amp;auml;uren &amp;amp; F&amp;ouml;rderung Fettabbau Di&amp;auml;t| Glavonoid - Japan


&lt;?php

$title='Schlankheitspillen Fat Burner | Abnehmen BMI Gewichts-Kontrolle l Fettverbrenner Gewichtabnahme| Appetitz&amp;uuml;gler - Unterdr&amp;uuml;ckung Fetts&amp;auml;uren &amp;amp; F&amp;ouml;rderung Fettabbau Di&amp;auml;t| Glavonoid - Japan';
echo html_entity_decode($title);

echo strlen(htmlspecialchars_decode($title));

//输出内容
Schlankheitspillen Fat Burner | Abnehmen BMI Gewichts-Kontrolle l Fettverbrenner Gewichtabnahme| Appetitzügler - Unterdrückung Fettsäuren &amp; Förderung Fettabbau Diät| Glavonoid - Japan

猜你会用到一下内容

PHP怎么将HTML实体转换为普通字符

<?php

$my_str = "I&#039;m good &amp; &lt;b&gt;&quot;boy &quot;&lt;/b&gt;.";

echo htmlspecialchars_decode($my_str);

echo "<br>";

echo htmlspecialchars_decode($my_str, ENT_QUOTES);

echo "<br>";

echo $my_str;

 

 

 

微信小程序 res =>的意义及userInfoReadyCallback函数的作用

刚开始接触微信小程序,想写个迷你计算器的小程序,感觉开发挺方便的,当准备使用用户信息时,打算看一下它是怎么获取用户信息的,为之后获取用户openid准备。获取用户信息主要在app.js 和 index.js中

代码中的 res =>可以理解为function(res),其中res即为返回的数据结果对象,不知道又是哪新出的语法规则(后来补充,这个是ES6的箭头函数,


App({
onLaunch: function () {
// 展示本地存储能力
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)

// 登录
wx.login({
success: res => {
}
})
// 获取用户信息
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
this.globalData.userInfo = res.userInfo

// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
}
})
},
globalData: {
userInfo: null,
}
})

index.js


/index.js
//获取应用实例
const app = getApp()

Page({
data: {
motto: '欢迎使用迷你计算器',
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo')
},
//事件处理函数
bindViewTap: function() {
wx.navigateTo({
url: '../logs/logs'
})
},

onLoad: function () {
if (app.globalData.userInfo) {
this.setData({
userInfo: app.globalData.userInfo,
hasUserInfo: true
})
} else if (this.data.canIUse){
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
app.userInfoReadyCallback = res => {
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
} else {
// 在没有 open-type=getUserInfo 版本的兼容处理
wx.getUserInfo({
success: res => {
app.globalData.userInfo = res.userInfo
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
})
}
},

getUserInfo: function(e) {
console.log(e)
app.globalData.userInfo = e.detail.userInfo
this.setData({
userInfo: e.detail.userInfo,
hasUserInfo: true
})
}
})

首先执行的是app.js的wx.getUserInfo,这个是获取用户信息的网络请求,由于其返回结果不知道在index页面加载完成之前还是之后完成,因此分为两种情况:

在index页面加载完成之前返回:此时优先执行app.js中success函数的代码,app.globalData.userInfo就保存了用户信息。运行到这里时,由于userInfoReadyCallback函数是在index.onload中定义的,因此此时该函数并没有被定义,所以不执行该函数。之后执行index.js中onload中的代码,执行第一个if分支,赋值给页面的userInfo和hasUserInfo
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
在index页面加载完成之后返回:此时优先执行index.js中onload中的代码,由于用户信息还没有返回,所以app.globalData.userInfo为null,执行第二个if分支,定义userInfoReadyCallback函数。随后数据被返回,执行success的代码,app.globalData.userInfo在此时才保存了用户的信息,并执行userInfoReadyCallback函数,赋值给页面的userInfo和hasUserInfo
因此总体来说userInfoReadyCallback函数的作用,就是保证页面的userInfo和hasUserInfo被正确赋值,无论用户信息在页面加载完成之前还是之后返回。

原文链接:https://blog.csdn.net/zjw_python/article/details/80641963