解决僵死进程defunct方式

Publish: September 14, 2017 Category: C/C++ No Comments

这里有以下几种方式解决僵死进程:

忽略子进程退出信号

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <strings.h>

void sig_catch( int sig, void (*f) () )
{
    struct sigaction sa;
    sa.sa_handler = f;
    sa.sa_flags   = 0;
    sigemptyset(&sa.sa_mask);
    sigaction(sig, &sa, (struct sigaction *) 0);
}

sig_catch(SIGCHLD, SIG_IGN);


2. 父进程wait子进程退出信号

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <strings.h>

#define wait_crashed(w) ((w) & 127)
#define wait_exitcode(w) ((w) >> 8)

int wait_pid(int *wstat, int pid)
{
    int r;
    do
        r = waitpid(pid, wstat, 0);
    while ((r == -1) && (errno == EINTR));
    return r;
}


int main(int argc, char **argv) 
{
    pid_t   pid;

    switch (pid = fork()) {
        case -1:
            printf("fork error\n");
            return 1;
        case 0:
            printf("child[%d]: exit\n");
            _exit(31);
    }

    int wstat;
    int exitcode;

    int pid_w = wait_pid(&wstat, pid);
    if (pid_w != pid) {
        printf("waitpid fail. pid_w[%lld] pid[%lld]\n", pid_w, pid);
        return 1;
    }
    
    if (wait_crashed(wstat)) {
        printf("waitpid crashed \n");
        return 1;
    }
    
    exitcode = wait_exitcode(wstat);
    printf("child[%lld] exit code[%d]\n", pid, exitcode);

    return 0;
}


3. Catch子进程信号,并在处理函数内wait (注意这个函数里不可以做syslog调用,在大量并发时会程序异常)

// 此函数内不可调用syslog
void sigchld_exit()
{
    int exitcode;
    int wstat, pid;
    while ((pid = waitpid(-1, &wstat, WNOHANG)) > 0) {
        //log_info("child[%ld] exit[%d]", pid, wstat);
        if (wait_crashed(wstat)) {
            //log_error("child[%ld] crashed[%d]", pid, wstat);
            return;
        }   
        exitcode = wait_exitcode(wstat);
        //log_info("child[%ld] exitcode[%d]", pid, exitcode);
    }   
}

{
    sig_catch(SIGCHLD, sigchld_exit);
}

inetd,xinetd守护进程

Publish: August 31, 2017 Category: Shell,C/C++ No Comments

    inetd, xinetd 为每一个服务都建立侦听socket,当inetd,xinetd收到连接时,它首先确定该socket协议和端口所对应的服务程序,然后fork子进程来启动exec该服务程序,并把连接的通信socket描述符作为标准输入、标准输出和标准错误输出描述符传递给子进程。

    这种方式,不但不需要为每个服务启动独立的服务程序,而且在设计这些服务程序时,还可以避免考虑复杂的socket编程,所需的仅仅是简单的字符串分析。比如telnet、ftp等,都是通过 inetd, xinetd 守护进程来实现的。


xinetd:

  1. 设置文件: /etc/services

# 在文件尾添加一行:
sj    20227/tcp

此文件记录了 xinetd 守护的每个服务的基本信息,包括名称、端口号和协议类型。此例添加了服务 sj 占用TCP协议的20227端口。


  2. 设置文件: /etc/xinetd.d/sj

service sj
{
    socket_type = stream
    protocol    = tcp 
    wait        = no
    user        = root
    only_from   = 198.72.5.0 localhost  
    banner      = /usr/home/grayson/deny_banner
    server      = /usr/home/grayson/sj_server
}

这是一个常见的服务配置文件。我们逐行看一下:

  • 第一行指定这是一个服务并给服务取一个名称。

  • socket_type 描述连接如何工作,常常是 stream(用于 TCP 连接)或 dgram(用于 UDP 服务)。

  • wait 控制 xinetd 是每次处理一个连接 (wait=yes),还是每次处理多个连接 (wait=no)。

  • user 指定守护进程应该作为哪个用户运行。这个用户常常是根用户(超级用户),但是某些服务最好或必须作为服务的创建者运行。

  • only_from 指定哪些系统可以对这个服务发出请求。在这里,只允许 198.72.5 子网上的系统和本地主机使用 sj 服务。最右边的 0 作为通配符;允许 IP 地址前缀为 198.72.5 的任何系统请求服务。可以使用多种表示法指定系统;详情参见 xinetd.conf 手册页。(输入 man 5 xinetd.conf。)如果允许所有就去掉这行!

  • 如果禁止访问,就把 /usr/local/etc/deny_banner 文件的内容发送给客户机。

  • 最后,server 指定允许访问时运行的可执行程序。


  3. 重启服务:

service xinetd restart

    

  4. 服务: sj_server

#include <stdio.h>
int main()
{
    char buf[1024] = {0};
    printf("Welcome!\n");
    fflush(stdout);
    while (1) {
        fgets(buf, sizeof(buf), stdin);     // 读取请求
        printf("Input: %s", buf);           // 返回应答
        fflush(stdout);
        if (strncmp(buf, "exit", 4) == 0)
            break;
    }
    return 0;
}

  5. 编译

# gcc -g -o sj_server sj_server.c


Smail删除队列中的文件

Publish: August 9, 2017 Category: 个人 No Comments

1. 获取队列MID号:

# /var/qmail/bin/smailctl qinfo
Aug 09 06:01:13 +0800 CST mid:63399927918638  size:777  <> 
        remote  123@aabbcc.com
Aug 08 14:30:10 +0800 CST mid:2482662363340  size:2332  <> 
        remote  456@cdef.com

2. 获取该队列的hash位置:

# tree /var/qmail/queue/info/ |grep -B1 63399927918638
├── 4
│   └── 63399927918638

3. 删除信封和信体文件:

# rm -f /var/qmail/queue/info/4/63399927918638
# rm -f /var/qmail/queue/mess/4/63399927918638


一行命令查询出所在hash:

#/var/qmail/bin/smailctl qinfo |grep ' mid:' |awk -F' mid:' '{print $2}' |awk '{print "tree /var/qmail/queue/info |grep -B1 "$1}' |sh
└── 9
    └── 6439711977012
├── 13
│   └── 119909357986622524
├── 15
│   └── 7884062363327
├── 16
│   └── 119909521195720018
├── 19
│   └── 9592328016178
├── 20
│   └── 4882731976441
├── 21
│   ├── 5631502363341
│   ├── 5631502363341
│   └── 64876127918686
│   ├── 74365027918567
│   └── 90805427918544
├── 22
│   ├── 3397551976426
│   ├── 3397551976426
│   ├── 74365027918567

然后再去处理

CentOS一键升级内核并开启Google BBR

Publish: April 21, 2017 Category: Shell No Comments

Google BBR是一款TCP加速工具,类似与锐速,Google开源了BBR 拥塞控制算法,并提交到了 Linux 内核,最新的 4.9 版内核已经用上了该算法。因此要想使用BBR,必须升级到最新内核。


查看架构

OpenVZ虚拟化不支持单独升级内核,因此可以直接放弃。KVM、XEN等虚拟化一般是支持的。CentOS执行下面的命令可以查看当前使用的虚拟化技术,详细说明请参考:

#安装virt-whatyum 
install virt-what

#查看架构
virt-what

升级内核并开启BBR

依次执行下面的命令升级内核并开启BBR,执行完毕后需重启服务器,若内核升级失败导致系统无法启动,可以参考《CentOS 6修改启动内核》处理,升级前重要数据请做好备份,勿在生产环境测试。

#分别执行下面的命令升级内核
wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh
chmod +x bbr.sh
./bbr.sh

查看

#查看内核版本,一般返回4.9
uname -r

#执行下面命令,一般返回net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_available_congestion_control

#下面命令一般返回net.ipv4.tcp_congestion_control = bbr
sysctl net.ipv4.tcp_congestion_control

#下面命令一般返回net.core.default_qdisc = fq
sysctl net.core.default_qdisc

#返回值有 tcp_bbr 模块,说明BBR已启动

其它说明

一键脚本在Vultr测试通过,该脚本还适用于Debian 7+,Ubuntu 12+,具体请自行尝试。配合秋水逸冰的另一脚本CentOS一键安装shadowsocks脚本效果更佳。


本文引用: CentOS一键升级内核并开启Google BBR

联通在线打印发票流程

Publish: November 22, 2016 Category: 默认分类 No Comments

http://www.10010.com/bj/


充值交费:

    首页 --- 点击‘交费充值’ --- 输入手机号,交费金额选其它(自己填写100) --- 下一步 走充值流程


打印发票:

    首页 --- 话费查询 --- 电子发票查询及开具 --- 实缴发票 --- 点选要开的发票 --- 右侧点“立即开电子发票” --- 输入手机号和邮箱 --- 下一步 确认办理

    收到短信后,刷新本页,该电子发票状态从‘开票中’变为‘可下载’, 点选后,右侧点击下载电子发票(PDF)


bst g22 jinniu lilai opebet orange88 vinbet xbet yuebo zunlong shijiebei bet007 hg0088 ju111 letiantang m88 mayaba qg777 qianyiguoji sbf777 tengbohui tlc ule weilianxier waiweitouzhu xingfayule xinhaotiandi yinheyule youfayule zhongying 2018shijiebei w88 18luck 188bet beplay manbet 12bet 95zz shenbo weide1946 ca88 88bifa aomenxinpujing betway bodog bt365 bwin tongbao vwin weinisiren 88jt fenghuangyule hongyunguoji 918botiantang huanyayule jianada28 jixiangfang libo long8 hongzuyishi zuqiutouzhu