月度归档 2016年1月31日

通过清心醉

php7.0.1-magento出现500错误

最近测试PHP7对magento的性能影响,结果出现500错误。一开始以为是伪静态出错搞的鬼,后来安装了个wordpress重写伪静态发现又没问题,后来GOOGLE了一翻:

在app/code/core/Mage/Core/Model/Layout.php文件里第555行:

$out .= $this->getBlock($callback[0])->$callback[1]();

修改为:$out .= $this->getBlock($callback[0])->{$callback[1]}();

就可以解决问题了。

通过清心醉

实战B2B模式使用Nginx+Apache站群

该方法主要涉及较多其实为NGINX的反向代理+负载均衡再加上APACHE的后端数据处理。

以下只为思路,更多细节的问题未能写出,作者以VM虚拟机进行多站点测试进行大数据网站服务器站群编写。

这作者假设我有4台服务器

服务器1:NGINX,作为反向代理+负载均衡+静态文件(比如IMG/JS/CSS等); IP:192.168.1.200

服务器2:MYSQL数据集群;IP:192.168.1.220

服务器3:APACHE+PHP核心代码程序运行库 IP:192.168.1.231

服务器4:APACHE+PHP核心代码程序运行库 IP:192.168.1.232

首先,WEB的程序技术你得过关,能完整的划分开动、静态的文件

先来说说思路:

NGINX做为网站的主引导入口,用户访问的时候,NGINX反向代理请求给服务器3、4;

服务器响应过后,把数据返回给NGINX。

#注:在这里可以设置服务器3、4只允许服务器1的IP进行内网访问,服务器2因为是数据库服务器,所以只允许服务器3、4进行访问。而对外访问接口只提供NGINX一个对外接口。

居然NGINX请求给了3、4的APACHE+PHP服务器,那么服务器3、4就必须连接MYSQL。(在这一点上如果你不知道PHP如何连接其他主机的MYSQL,那么我可以知道你没有程序的读写能力,劝你好好去学习学习吧)。

好了,服务器3、4请求服务器2的MYSQL毫无压力,服务器2的配置可以用最高配,因为数据库瓶颈一直也是个问题(当然也可以使用更多的服务器做MYSQL,进行MYSQL数据库的同步工作,瓶颈基本就可以得到很好的解决,因为作者没去了解过MYSQL数据同步,所以暂时以一台服务器做讲解)。

好吧,作者说说最大的问题点吧。

1:NGINX的负载均衡,把访问的请求均衡转发给服务器3、4;

方法1:循环反向代理模式

nginx.conf的http节点内添加:

upstream ipanying{
      server 192.168.1.231:88;
      server 192.168.1.232:88;
}

然后在server节点内

直接使用:

proxy_pass http://ipanying;

反向代理给IP=192.168.1.231和192.168.1.232的服务器

以上upstream使用的是循环制,即第一次访问的是231的IP,第二次访问的是232的IP,然后又回到231,以此类推。

 

方法2:根据访问IP的方式(推荐)

继续修改upstream模式:

upstream ipanying{
ip_hash;
server 192.168.1.231:88;
server 192.168.1.232:88;
}

作者为什么会推荐该模式,因为用户访问,可能会根据IP、COOKIE等做信息处理。

还有最主要的是如果有涉及登录模式的话,用户登录的SESSION所在的服务器集不一,这样一来的话,下次分发到另外的服务器的时候,可能会导致IP统计不准确或者SESSION丢失等问题。

更多的方法可以GOOGLE “upstream ”;

 

方法3:权重反向代理模式

修改上文中的:

upstream ipanying{
      server 192.168.1.231:88 weight=2;
      server 192.168.1.232:88 weight=10;   
}

权重反向有什么好处呢?

比如231的IP的服务器只有4G内存,CPU只有2核,就不能进行太多的请求,如果使用循环制,怕跑太辛苦,

可是第二台权重=10又是什么意思

因为我第二台服务器有64G内存,24核CPU,我想更多的用户都主要以该服务器为主,偶尔转发几个给IP231的服务器,权重反向模式绝对是最佳模式;当然该方法仅适于展示的网站,不存在SESSION等信息的时候。

 

2:NGIXN的静态文件及服务器3、4动态文件的处理;

在这特别说下,服务器3、4只存在PHP和视图文件。不参与一切img\js\css等静态文件的存放,这些文件只能放在NGINX下

NGINX在进行均衡反向的时候,自身同时也把静态文件发送给用户。

比如登录PHP网站后台,生成的图片,上传的媒体文件等,通过方法放在NGINX的ROOT指定目录,这点就PHP的技术上来说,实现不难。

顺便贴下作者B2B的服务器群组部署:

/admin 管理员后台

/data 网站前台

/shangjia 商家后台

以上3目录只包含PHP和tpl和phtml文件,因为文件相同,分别部署服务器3、4

然后是NGINX

/img

/cssjs

实现的方法就是商家上传的图片,放在NGINX服务器的img内,这样就可以进行数据相应了。

作者上文写了Linux+Apache+Nginx+Mysql+Php真的适合所有的单一服务器网站吗?

利用NGINX的反向优势来进行评测,现在这篇文章是让更多的人知道,LANMP,适合的不是单一服务体,更多的是大群体服务器。

 

 

通过清心醉

深入理解NGINX反向代理

NGINX由于占用资源少,并且吞吐/并发量是HTTP SERVER的老大。

一般的站点都会使用NGINX做前端,APACHE做后端。

但如果是一台服务器上做,有点白费心机。

比如WDCP等Linux+Apache+Nginx+Mysql+Php集成扩展。

为什么说白费心机,作者晚点会写个实战B2B模式使用Nginx+Apache站群进行网络群体覆盖的数据来详细说明。

NGINX居然做为反向代理,那么其最大的优势就是可以反向给APACHE、IIS(WINDOWS下作者没写过)等其他后端集,好吧,NGINX可以承载很大的吞吐并发量,特别针对静态数据。

问题来了,现在的站点9成以上使用的是伪静态数据,如果用户不进行缓存,每次的请求存在动态数据,一样会反向给APACHE等后端,APACHE后端同样进行动态操作,然后返回给NGINX,NGINX呈现给用户,这样,NGINX和APACHE等后端同样要占用资源来进行相应的操作,那么如此做,是不是有点多次一举?如果要说GZIP等压缩技术,APACHE完全都是可以胜任的。所以,单一服务器其实根本没必要使用LANMP组合,完全浪费系统资源,虽然APACHE来进行的话,占用资源高,释放慢,但基本都是可以保证相应需求的,而且NGINX反向给APACHE,APACHE释放资源慢的问题一样不会及时解决,那么,单一服务器/VSP有什么必要使用LANMP呢?

如果要说必须使用LANMP的必须条件,作者感觉只有DEDECMS这款程序了,使用的是生成完全的静态文件,就生成的时候数据库瓶颈有点大,生成之后是纯静态文件,这样,NGINX的性能优势就能完全的发挥出来,APACHE只是用户在进行动态操作及后端生成文件的时候占用会资源,但不久后就被释放。

提供给还在为系统架构烦恼的系统架构师们!

通过清心醉

nginx性能优化之nginx.conf优化配置

作者的服务器为双核配置,内存就不说了:

以下数据以NGINX做反向代理所做优化

贴贴NGINX核心配置应该修改的参数:

worker_processes     2;  

worker_cpu_affinity 01 10;

worker_processes 为开启的进程数;一般为CPU的核数。

worker_cpu_affinity 01 10为开启的CPU进行

 

当然,如果观察CPU的资源使用不是很大,可以开启4进程:

worker_processes     4;  

worker_cpu_affinity 01 10 01 10;  

请根据自身CPU的使用率来进行调节

2核是 01,四核是0001,8核是00000001,有多少个核,就有几位数,1表示该内核开启,0表示该内核关闭。 worker_processes最多开启8个,8个以上性能提升不会再提升了,而且稳定性变得更低,所以8个进程够用了。 配置完毕后,重启nginx 。

worker_processes: 官方英文版wiki配置说明中的描述如下,个人理解为worker角色的进程个数(nginx启动后有多少个worker处理http请求。master不处理请求,而是根据相应配置文件信息管理worker进程.   master进程主要负责对外揽活(即接收客户端的请求),并将活儿合理的分配给多个worker,每个worker进程主要负责干活(处理请求))。 syntax:worker_processes number | auto; default: worker_processes 1; context:main Defines the number of worker processes.

 

接下来是worker_connections

控制每个进程打开的文件的数量,默认使用系统的配置1024为最大值。

测试最大的吞吐量的时候

max clients的公式=worker_processes*worker_connections/4

一般1024的值基本足够,不建议修改过大,作者修改为4096。

不过由于系统限制是1024,所以我们需要修改下LINUX的配置

否则重启NGINX就会报错:

[warn]: 3660#0: 4096 worker_connections are more than open file resource limit: 1024 !!

修改/etc/security/limits.conf文件,

在文件中添加如下行:

* soft noproc 4096
* hard noproc 4096
* soft nofile 4096
* hard nofile 4096

就是限制了任意用户的最大线程数和文件数为65535。 其中*(注意有个空格)为所有用户的打开文件数限制,可用’*’号表示修改所有用户的限制;soft或hard指定要修改软限制还是硬限制;10240则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制)。修改完后wq;

 

修改/etc/pam.d/login文件,在文件中添加如下行:

session required /lib/security/pam_limits.so

这是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对该用户可使用的各种资源数量的最大限制(包括用户可打开的最大文件数限制),而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。修改完后wq。

修改/etc/rc.local脚本,在脚本中添加如下行:

echo “4096”> /proc/sys/fs/file-max

这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为4096

好了重启下

重新修改nginx.conf

events前面添加:

worker_rlimit_nofile 4096;

限制最大的文件数量

以下为作者完整的nginx.conf

worker_processes 2;
worker_cpu_affinity 01 10;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_rlimit_nofile 4096;
events {
worker_connections 4096;
}
http {
server_tokens off;
include /usr/local/nginx/mime.types;
include /usr/local/nginx/proxy.conf;
include /usr/local/nginx/gzip.conf;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
client_header_buffer_size 2k;
large_client_header_buffers 4 4k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;

sendfile on;
keepalive_timeout 65;

log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;

access_log /var/log/nginx/access.log main;

#gzip on;
server {
listen 80 default_server;
server_name _;
return 404;
}
include /usr/local/nginx/conf.d/*.conf;
}

 

 

通过清心醉

php添加pdo_mysql扩展

由于作者是完全编译安装的,所以需要进入编译的源文件里:

cd /temp/php-5.6.17/ext/pdo_mysql;

执行下:

/usr/local/php-5.6/bin/phpize

再预编译:

./configure –with-php-config=/usr/local/php-5.6/bin/php-config –with-pdo-mysql=/uar/local/mysql-5.6.24/

再编译安装:

make && make install

接着写入php.ini

echo “extension=/usr/local/php-5.6/lib/php/extensions/no-debug-non-zts-20121212/pdo_mysql.so” >> /mydata/php.ini

通过清心醉

Apache配置站点泛解析

作品前几篇文章写了:

Nginx配置域名泛解析

针对作者开发的盼盈网,由于是B2B的模式,需要对泛域名的解析

而且作者刚重构了WEB架构。APACHE的泛解析作者在进行共享:

首先我们要知道,Nginx把动态数据反向请求给apache

 

<VirtualHost 127.0.0.1:88>
DocumentRoot /var/www/ipanying
ServerName ipanying.com
ServerAlias *.ipanying.com
</VirtualHost>
<Directory “/var/www/ipanying”>
Options Indexes FollowSymLinks ExecCGI Includes
AllowOverride All
Require all granted
</Directory>

如此一来,apache就可以无限解析ipanying.com的二级域名了。

通过清心醉

dedecms-PHP5.3+版本后台无法注销解决方法

和登录一样,其实很简单,都是因为使用了废弃函数

利用$_SESSION重写exitUser()方法即可

/include/user/login.class.php

    function exitUser()
    {
        ClearMyAddon();
        /**
        @session_unregister($this->keepUserIDTag);
        @session_unregister($this->keepUserTypeTag);
        @session_unregister($this->keepUserChannelTag);
        @session_unregister($this->keepUserNameTag);
        @session_unregister($this->keepUserPurviewTag);
        */
        $_SESSION[$this->keepUserIDTag]=null;
        $_SESSION[$this->keepUserTypeTag]=null;
        $_SESSION[$this->keepUserChannelTag]=null;
        $_SESSION[$this->keepUserNameTag]=null;
        $_SESSION[$this->keepUserPurviewTag]=null;
        DropCookie(‘dedeAdmindir’);
        DropCookie(‘DedeUserID’);
        DropCookie(‘DedeLoginTime’);
        $_SESSION = array();
    }

通过清心醉

dedecms-PHP5.3+版本后台登录空白解决方法

首先我们看看请求的URL:

/admin/login.php

在$admindirs = explode(‘/’,str_replace(“\\”,’/’,dirname(__FILE__)));之前,打印下POST参数:

array(7) { [“gotopage”]=> string(0) “” [“dopost”]=> string(5) “login” [“adminstyle”]=> string(10) “newdedecms” [“userid”]=> string(5) “admin” [“pwd”]=> string(5) “admin” [“validate”]=> string(4) “DTCT” [“sm1”]=> string(6) “登录” }

接下来就有判断if($dopost==’login’),执行的是登录方法

$cuserLogin = new userLogin($admindir);

在这里进行了实例化userLogin,并且带个管理的目录参数

真郁闷,居然直接是构造方法来实现:

var $userName = ”;
var $userPwd = ”;
var $userID = ”;
var $adminDir = ”;
var $userType = ”;
var $userChannel = ”;
var $userPurview = ”;
var $keepUserIDTag = ‘dede_admin_id’;
var $keepUserTypeTag = ‘dede_admin_type’;
var $keepUserChannelTag = ‘dede_admin_channel’;
var $keepUserNameTag = ‘dede_admin_name’;
var $keepUserPurviewTag = ‘dede_admin_purview’;
var $keepAdminStyleTag = ‘dede_admin_style’;
var $adminStyle = ‘dedecms’;

 

function __construct($admindir=”)
{
global $admin_path;
if(isset($_SESSION[$this->keepUserIDTag]))
{
$this->userID = $_SESSION[$this->keepUserIDTag];
$this->userType = $_SESSION[$this->keepUserTypeTag];
$this->userChannel = $_SESSION[$this->keepUserChannelTag];
$this->userName = $_SESSION[$this->keepUserNameTag];
$this->userPurview = $_SESSION[$this->keepUserPurviewTag];
$this->adminStyle = $_SESSION[$this->keepAdminStyleTag];
}

if($admindir!=”)
{
$this->adminDir = $admindir;
}
else
{
$this->adminDir = $admin_path;
}
}

 

我们在来看看数据成员:

 

var $userName = ”;
var $userPwd = ”;
var $userID = ”;
var $adminDir = ”;
var $userType = ”;
var $userChannel = ”;
var $userPurview = ”;
var $keepUserIDTag = ‘dede_admin_id’;
var $keepUserTypeTag = ‘dede_admin_type’;
var $keepUserChannelTag = ‘dede_admin_channel’;
var $keepUserNameTag = ‘dede_admin_name’;
var $keepUserPurviewTag = ‘dede_admin_purview’;
var $keepAdminStyleTag = ‘dede_admin_style’;
var $adminStyle = ‘dedecms’;

好吧,PHP5.3以前的语句真心难懂

写入了参数之后

$res = $cuserLogin->checkUser($userid,$pwd);

在这里有点好奇$userid,$pwd的参数原型,应该是/group/global.inc.php里定义的全局变量,没有去详细查看核心。

 

看看原型:

function checkUser($username,$userpwd)
{
global $dsql;

//只允许用户名和密码用0-9,a-z,A-Z,’@’,’_’,’.’,’-‘这些字符
$this->userName = ereg_replace(“[^0-9a-zA-Z_@!\.-]”,”,$username);
$this->userPwd = ereg_replace(“[^0-9a-zA-Z_@!\.-]”,”,$userpwd);
$pwd = substr(md5($this->userPwd),5,20);
$dsql->SetQuery(“Select admin.*,atype.purviews From `#@__admin` admin left join `#@__admintype` atype on atype.rank=admin.usertype where admin.userid like ‘”.$this->userName.”‘ limit 0,1″);
$dsql->Execute();
$row = $dsql->GetObject();
if(!isset($row->pwd))
{
return -1;
}
else if($pwd!=$row->pwd)
{
return -2;
}
else
{
$loginip = GetIP();
$this->userID = $row->id;
$this->userType = $row->usertype;
$this->userChannel = $row->typeid;
$this->userName = $row->uname;
$this->userPurview = $row->purviews;
$inquery = “update `#@__admin` set loginip=’$loginip’,logintime='”.time().”‘ where id='”.$row->id.”‘”;
$dsql->ExecuteNoneQuery($inquery);
$sql = “update #@__member set logintime=”.time().”, loginip=’$loginip’ where mid=”.$row->id;
$dsql->ExecuteNoneQuery($sql);
return 1;
}
}

通过正则方法判断帐号密码,然后执行SQL判断和更新登录信息

如果返回1

$cuserLogin->keepUser();

function keepUser()
{
if($this->userID != ” && $this->userType != ”)
{
global $admincachefile,$adminstyle;
if(empty($adminstyle)) $adminstyle = ‘dedecms’;

@session_register($this->keepUserIDTag);
$_SESSION[$this->keepUserIDTag] = $this->userID;

@session_register($this->keepUserTypeTag);
$_SESSION[$this->keepUserTypeTag] = $this->userType;

@session_register($this->keepUserChannelTag);
$_SESSION[$this->keepUserChannelTag] = $this->userChannel;

@session_register($this->keepUserNameTag);
$_SESSION[$this->keepUserNameTag] = $this->userName;

@session_register($this->keepUserPurviewTag);
$_SESSION[$this->keepUserPurviewTag] = $this->userPurview;

@session_register($this->keepAdminStyleTag);
$_SESSION[$this->keepAdminStyleTag] = $adminstyle;

PutCookie(‘DedeUserID’, $this->userID, 3600 * 24, ‘/’);
PutCookie(‘DedeLoginTime’, time(), 3600 * 24, ‘/’);

$this->ReWriteAdminChannel();

return 1;
}
else
{
return -1;
}
}

好吧,结果很清晰了,使用了废弃的函数,PHP5.3+应该使用$_SESSION的方法,修改下:

修改下该函数体:

function keepUser()
{
if($this->userID != ” && $this->userType != ”)
{
global $admincachefile,$adminstyle;
if(empty($adminstyle)) {
$adminstyle = ‘dedecms’;
}
$_SESSION[$this->keepUserIDTag] = $this->keepUserIDTag;
$_SESSION[$this->keepUserIDTag] = $this->userID;
$_SESSION[$this->keepUserTypeTag] = $this->keepUserTypeTag;
$_SESSION[$this->keepUserTypeTag] = $this->userType;
$_SESSION[$this->keepUserChannelTag] = $this->keepUserChannelTag;
$_SESSION[$this->keepUserChannelTag] = $this->userChannel;
$_SESSION[$this->keepUserNameTag] = $this->keepUserNameTag;
$_SESSION[$this->keepUserNameTag] = $this->userName;
$_SESSION[$this->keepUserPurviewTag] = $this->keepUserPurviewTag;
$_SESSION[$this->keepUserPurviewTag] = $this->userPurview;
$_SESSION[$this->keepAdminStyleTag] = $this->keepAdminStyleTag;
$_SESSION[$this->keepAdminStyleTag] = $adminstyle;
PutCookie(‘DedeUserID’, $this->userID, 3600 * 24, ‘/’);
PutCookie(‘DedeLoginTime’, time(), 3600 * 24, ‘/’);
$this->ReWriteAdminChannel();
return 1;

}
else
{
return -1;
}
}

 

成功解决!

通过清心醉

Fatal error: Call to undefined function ParCv() in C:\xampp\htdocs\include\dedesql.class.php on line 489

发现很多网络公司除了电子商城的使用,其他的就是CMS的使用了,而且DEDE的CMS基本是首选。 利用空余时间尝试安装了下,结果提示错误:

Fatal error: Call to undefined function ParCv() in C:\xampp\htdocs\include\dedesql.class.php on line 489

好吧,找不到ParCv方法。

直接ZENd F3抓去到了代码数据

require_once ‘common.func.php’;

问题搞定!

原因估计是经过其他高手进行修改,然后忘记包含或者其他文件包含错误的关系,详细的没去进行代码跟踪。

通过清心醉

个人网站开发需要前后端技术才行吗?

有人说,个人技术开发需要前后结合,我笑了.

WEB部署,要看张宴,几年前的一篇<实战Nginx:取代Apache的高性能Web服务器>

让更多的人接触认识了Nginx的强大并且更好的使用开源系统抛弃IIS.

然后经历过几年的不断变更,出现LANMP的服务器组合(Linux+Apache+Nginx+Mysql+Php).

SEO优化,要看郑志平,国内白帽SEO高手之一.

同为80后,两个都是在CEO的岗位.试问,有多少做前端UI的,能有这个能力和价值?

一个纯WEB部署及后端开发及数据挖掘的张宴,成就的是WEB平台的安全稳定.

一个纯SEO优化,成就的是网站流量到来的直接效益.

没错,前端是和用户沟通的桥梁,后端是运营的基础.可是如果和用户沟通的再好再强大,没有一个强大的WEB支柱没有SEO的世界宣传,效果UI不能保证长期效益.

专著于后端技术-成就于安全高效.

通过清心醉

PHP开启INTL扩展之WINDOWS版

为了测试新的magento开源系统,所以在当前的WIN系统内安装了个WAMP快速部署环境.
安装完成之后,发现新的magento电子商城程序需要INTI的扩展支持
好吧,WINDOWS下的扩展开启比较简单,果断php.ini里打开extension=php_intl.dll
重启APACHE,发现还是存在对应的问题,提示扩展未开启
经过GOOGLE一翻,发现问题不在该扩展上,而是扩展以来的其他扩展文件的关系.
PHP的根目录有很多icu***50.dll文件 (50表示的是当前的PHP的版本,**为所有的文件名)
把文件复制到apache/bin/目录内,重启搞定!

更多直接打印phpinfo查看!

注: 新版MAGENTO为MAGNETO VER 2.0,如果需要进行二次开发建议使用UNIX,否则几万个文件,你的ZEND刷新项目就卡你一个多小时!

通过清心醉

微信公众平台也许你不知道的恶心东西

首先说一下,不是谁都离不开你腾讯,只是你有能力垄断一定的沟通桥梁。
在我看来,吃饱没事玩手机还你妹的要玩腾讯的。要么就是无聊的孩子,要么就是没心思工作的人,根本就没有把心放在事业上的一个失败者。
好了,骂腾讯是为了解气,顺便说一句国内的软件产品8成以上基本只能放在虚拟机上。
回到正题,公众平台,现在满世界的吸粉吸粉,吸粉盈利。
很多进行吸粉的都是企业级,我就实在想不明白了,居然是企业,你还借助他人的企业干嘛?
顺便说说O2O京东,那么多的商家进去了,你要找个IPHONE 6S 基本都是京东自营。商家进去只是帮助京东进行一种宣传而已。
公众平台一样如此,用图说话吧:
1 2 3
真你妈的搞笑,只要是公众平台发布的文章,必须带广告。
好吧,回到主题,那么多的公众平台运营商,你们吸粉有了一定的优势,但其实你们也只是在给腾讯广告做宣传而已。
腾讯吃了肉,也许能喝到点汤水。
有实力的企业公司,建议你们自己做个属于自己独立域名的网站吧,你做的微小的效果对你没用但对腾讯却有效。
有实力为什么不自己创建一个属于自己企业级形象的平台,哪怕是用WORDPRESS来做?