当前位置:  互联网>综合
本页文章导读:
    ▪编程之美---中国象棋将帅问题      题目链接:http://www.msra.cn/Articles/ArticleItem.aspx?Guid=4c86d636-04bb-4ad9-b0bc-4c3496d18021#. 给出c++实现的简单代码: #include <iostream> #include <cstdio> using namespace std; const unsigned char fullmark=255; /.........
    ▪Nginx学习之八-惊群问题      惊群问题(thundering herd)的产生 在建立连接的时候,Nginx处于充分发挥多核CPU架构性能的考虑,使用了多个worker子进程监听相同端口的设计,这样多个子进程在accept建立新连接时会有争抢,.........
    ▪Dedecms的安全设置      最近一段时间基于DEDECMS做的网站,很多人都被黑了,我的小站也不幸中招了,没办法,只能上去做点安全防范工作了。 1. 打补丁,地址: http://www.dedecms.com/pl/ 2.Linux文件安全设置: 针对.........

[1]编程之美---中国象棋将帅问题
    来源: 互联网  发布时间: 2013-10-26

题目链接:http://www.msra.cn/Articles/ArticleItem.aspx?Guid=4c86d636-04bb-4ad9-b0bc-4c3496d18021#.

给出c++实现的简单代码:

#include <iostream>
#include <cstdio>
using namespace std;
const unsigned char fullmark=255; //11111111 
const unsigned char L_mask=fullmark<<4;//11110000
const unsigned char R_mask=fullmark>>4; //00001111
void RSET(unsigned char &b,int n)
{
	b=b&L_mask;
	b=b|n;
}
void LSET(unsigned char &b,int n)
{
	b=b&R_mask;
	b=b|(n<<4);
}
unsigned int rget(unsigned char b)//注意这里不能传引用 
{
	b=b&R_mask;
	return (unsigned int)b;
}
unsigned int lget(unsigned char b)//不能传引用 
{
	b=b&L_mask;
	b=b>>4;
	return (unsigned int)b;
}
int main()
{
	unsigned char b=0;
	LSET(b,1);
	//RSET(b,1);  //注意这里内存初始化不能放在外面 
	for(;lget(b)<=9;LSET(b,lget(b)+1))
		for(RSET(b,1);rget(b)<=9;RSET(b,rget(b)+1))
		{
			if(lget(b)%3!=rget(b)%3){
				cout<<"a=: "<<lget(b)<<", b=: "<<rget(b)<<endl;
			}
		} 
	return 0;	
}

这是传统的解法,下面的代码使用了位域的知识,比较简洁:

#include <iostream>
using namespace std;
struct node {
	unsigned char a:4;
	unsigned char b:4;
}i;
int main()
{
	for(i.a=1;i.a<=9;i.a++)
		for(i.b=1;i.b<=9;i.b++)
		{
			if(i.a%3!=i.b%3){
				cout<<"A=: "<<int(i.a)<<", B=: "<<int(i.b)<<endl;
			}
		}
	return 0;	
} 


作者:xiaozhuaixifu 发表于2013-7-6 21:40:12 原文链接
阅读:0 评论:0 查看评论

    
[2]Nginx学习之八-惊群问题
    来源: 互联网  发布时间: 2013-10-26
惊群问题(thundering herd)的产生

在建立连接的时候,Nginx处于充分发挥多核CPU架构性能的考虑,使用了多个worker子进程监听相同端口的设计,这样多个子进程在accept建立新连接时会有争抢,这会带来著名的“惊群”问题,子进程数量越多越明显,这会造成系统性能的下降。

一般情况下,有多少CPU核心就有配置多少个worker子进程。假设现在没有用户连入服务器,某一时刻恰好所有的子进程都休眠且等待新连接的系统调用(如epoll_wait),这时有一个用户向服务器发起了连接,内核在收到TCP的SYN包时,会激活所有的休眠worker子进程。最终只有最先开始执行accept的子进程可以成功建立新连接,而其他worker子进程都将accept失败。这些accept失败的子进程被内核唤醒是不必要的,他们被唤醒会的执行很可能是多余的,那么这一时刻他们占用了本不需要占用的资源,引发了不必要的进程切换,增加了系统开销。

如何解决惊群问题-post事件处理机制

很多操作系统的最新版本的内核已经在事件驱动机制中解决了惊群问题,但Nginx作为可移植性极高的web服务器,还是在自身的应用层面上较好的解决了这一问题。
Nginx规定了同一时刻只有唯一一个worker子进程监听web端口,这一就不会发生惊群了,此时新连接事件只能唤醒唯一的正在监听端口的worker子进程。

如何限制在某一时刻是有一个子进程监听web端口呢?在打开accept_mutex锁的情况下,只有调用ngx_trylock_accept_mutex方法后,当前的worker进程才会去试着监听web端口。

那么,什么时候释放ngx_accept_mutex锁呢?
显然不能等到这批事件全部执行完。因为这个worker进程上可能有许多活跃的连接,处理这些连接上的事件会占用很长时间,其他worker进程很难得到处理新连接的机会。

如何解决长时间占用ngx_accept_mutex的问题呢?这就要依靠post事件处理机制,Nginx设计了两个队列:ngx_posted_accept_events队列(存放新连接事件的队列)和ngx_posted_events队列(存放普通事件的队列)。这两个队列都是ngx_event_t类型的双链表。定义如下:
ngx_thread_volatile ngx_event_t  *ngx_posted_accept_events;
ngx_thread_volatile ngx_event_t  *ngx_posted_events;

下面结合具体代码进行分析惊群问题的解决。

首先看worker进程中ngx_process_events_and_timers事件处理函数(src/event/ngx.event.c),它处于worker进程的ngx_worker_process_cycle方法中,循环处理时间,是事件驱动机制的核心,既会处理普通的网络事件,也会处理定时器事件。ngx_process_events_and_timers是Nginx实际处理web业务的方法,所有业务的执行都是由它开始的,它涉及Nginx完整的事件驱动机制!!特别重要~
void
ngx_process_events_and_timers(ngx_cycle_t *cycle)
{
    ngx_uint_t  flags;
    ngx_msec_t  timer, delta;

    if (ngx_timer_resolution) {
        timer = NGX_TIMER_INFINITE;
        flags = 0;

    } else {
        timer = ngx_event_find_timer();
        flags = NGX_UPDATE_TIME;

#if (NGX_THREADS)

        if (timer == NGX_TIMER_INFINITE || timer > 500) {
            timer = 500;
        }

#endif
    }

    /*ngx_use_accept_mutex表示是否需要通过对accept加锁来解决惊群问题。当使用了master模式,nginx worker进程数>1时且配置文件中打开accept_mutex时,这个标志置为1 
    它在函数ngx_event_process_int中被设置,源代码为:
    if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) {
        ngx_use_accept_mutex = 1;
        ngx_accept_mutex_held = 0;
        ngx_accept_mutex_delay = ecf->accept_mutex_delay;

    } else {
        ngx_use_accept_mutex = 0;
    }*/
    if (ngx_use_accept_mutex) {
        //负载均衡处理
        if (ngx_accept_disabled > 0) {
            ngx_accept_disabled--;

        } else {
            //调用ngx_trylock_accept_mutex方法,尝试获取accept锁
            if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
                return;
            }

            //拿到锁
            if (ngx_accept_mutex_held) {
                /*给flags增加标记NGX_POST_EVENTS,这个标记作为处理时间核心函数ngx_process_events的一个参数,这个函数中所有事件将延后处理。会把accept事件都放到ngx_posted_accept_events链表中,epollin|epollout普通事件都放到ngx_posted_events链表中 */
                flags |= NGX_POST_EVENTS;
            } else {
                /*获取锁失败,意味着既不能让当前worker进程频繁的试图抢锁,也不能让它经过太长事件再去抢锁
                下面的代码:即使开启了timer_resolution时间精度,牙需要让ngx_process_change方法在没有新事件的时候至少等待ngx_accept_mutex_delay毫秒之后再去试图抢锁
                而没有开启时间精度时,如果最近一个定时器事件的超时时间距离现在超过了ngx_accept_mutex_delay毫秒,也要把timer设置为ngx_accept_mutex_delay毫秒,这是因为当前进程虽然没有抢到accept_mutex锁,但也不能让ngx_process_change方法在没有新事件的时候等待的时间超过ngx_accept_mutex_delay,这会影响整个负载均衡机制*/
                if (timer == NGX_TIMER_INFINITE
                    || timer > ngx_accept_mutex_delay)
                {
                    timer = ngx_accept_mutex_delay;
                }
            }
        }
    }

    //计算ngx_process_events消耗的时间
    delta = ngx_current_msec;

    //事件处理核心函数
    (void) ngx_process_events(cycle, timer, flags);

    delta = ngx_current_msec - delta;

    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                   "timer delta: %M", delta);

    //ngx_posted_accept_events链表有数据,开始accept新连接
    if (ngx_posted_accept_events) {
        ngx_event_process_posted(cycle, &ngx_posted_accept_events);
    }

    //释放锁后再处理ngx_posted_events链表中的普通事件
    if (ngx_accept_mutex_held) {
        ngx_shmtx_unlock(&ngx_accept_mutex);
    }

    //如果ngx_process_events消耗的时间大于0,那么这是可能有新的定时器事件触发
    if (delta) {
        //处理定时器事件
        ngx_event_expire_timers();
    }

    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                   "posted events %p", ngx_posted_events);

    //ngx_posted_events链表中有数据,进行处理
    if (ngx_posted_events) {
        if (ngx_threaded) {
            ngx_wakeup_worker_thread(cycle);

        } else {
            ngx_event_process_posted(cycle, &ngx_posted_events);
        }
    }
}

上面代码中要进行说明的是,flags被设置后作为函数ngx_process_events方法的一个参数,在epoll模块中这个接口的实现方法是ngx_epoll_process_events(其具体代码见http://blog.csdn.net/xiajun07061225/article/details/9250341)。当falgs标志位含有nGX_POST_EVENTS时是不会立即调用事件的handler回调方法的,代码如下所示:
 //事件需要延后处理
            if (flags & NGX_POST_EVENTS) {
                /*如果要在post队列中延后处理该事件,首先要判断它是新连接时间还是普通事件
                以确定是把它加入到ngx_posted_accept_events队列或者ngx_posted_events队列中。*/
                queue = (ngx_event_t **) (rev->accept ?
                               &ngx_posted_accept_events : &ngx_posted      
    
[3]Dedecms的安全设置
    来源: 互联网  发布时间: 2013-10-26

最近一段时间基于DEDECMS做的网站,很多人都被黑了,我的小站也不幸中招了,没办法,只能上去做点安全防范工作了。



1. 打补丁,地址:

http://www.dedecms.com/pl/


2.Linux文件安全设置:

针对部分文件夹,去掉可写权限

chmod -R 555 ask data dede include plus images templets

chmod -R 755 a uploads(此处处理还不够好,实际上我们应该对里面文件去除执行的操作,时间紧我们这么处理了)


3.Nginx服务器的配置:

location ~ /(uploads|templets|images|a)/.*\.(php|php5)?$ {
        deny all;
    }

a表示生成的静态文件

后台访问需要ip限制:

location /dede/ {
        allow 127.0.0.1;
        deny all;
    }

4.除此以外,需要对php的配置文件php.ini将一些不安全的设置关上,网上此类文章很多,稍候我会再列一些相关的方案。



作者:hunkxia 发表于2013-7-7 15:56:30 原文链接
阅读:6 评论:0 查看评论

    
最新技术文章:
 




特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3