分类目录归档:未分类

解决php下通过shell_exec git clone 报fatal: unable to set up default path; use –file 问题

报错:

fatal: unable to set up default path; use --file
fatal: could not read Username for 'http://10.100.11.5': No such device or address

demo 代码:

$giturl='http://10.100.11.5/appserver/appserver-api/';
$output=shell_exec("git clone {$giturl} 2>&1");
var_dump($output)

对应的www-data用户做了sudo 免密码

做了git免密码  (git config –global credential.helper store)

此代码在CLI命令行下运行正常

在apache下的web界面下报如题所示错误, 中间尝过许多办法。都无解。

思考过程:

1. su – www-data用户下的cli能正常运行,说明权限应该是没问题的

2. 分别在cli下和web下打印env相关东西

system("env");

结果发现两种情况下的环境变量相差很大。

尝试把web中的环境变量补充HOME变量后,问题解决了。

putenv("HOME=/home/www-data");
putenv("USER=www-data");
$giturl='http://10.100.11.5/appserver/appserver-api/';
$output=shell_exec("git clone {$giturl} 2>&1");

另一个解决办法:

默认的apache2.4会把HOME环境变量给unset 掉  见:/etc/apache2/envvars 第4行

# envvars - default environment variables for apache2ctl

# this won't be correct after changing uid
unset HOME   #就是这里

# for supporting multiple apache2 instances

针对apache的解决办法也比较简单了 修改envvars文件,  增加HOME环境变量的导出就行

#unset HOME   注释这里

# for supporting multiple apache2 instances
if [ "${APACHE_CONFDIR##/etc/apache2-}" != "${APACHE_CONFDIR}" ] ; then
        SUFFIX="-${APACHE_CONFDIR##/etc/apache2-}"
else
        SUFFIX=
fi

#增加这里
export HOME=/home/www-data

apachectl stop && apachectl start   (restart好像不会刷新环境变量)

问题解决, 解决此小问题,花费了好几个小时,都搞得有些怀疑自己的技术了。  ^_^

解决老旧设备 连接ftp 被动模式错误 Response: 227 Entering Passive Mode (10,1,0,9,85,148)”

原因分析:

1.FTP客户端代码自己写的, 代码比较阵旧

2.FTP服务器处于云主机的内网中,网卡设置的为内网IP,  虽然有绑定外网IP。  但是是做了NAT。

3.FTP服务器版本过高。

解决办法:

1.安装旧版本的ftp服务端  比如vsftpd-2.2.2-24.el6.x86_64

2./etc/vsftpd/vsftpd.conf

anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
pasv_address=118.3.2.1

 

解决ambari 集群磁盘空间满后 集群启动失败问题

1.同事反映某ambari集群访问不了,故登陆上去, 发现几个节点的磁盘空间全占满了,细查了一下,发现zk日志占用巨大。 当时以为很简单,删除日志,腾出空间,再重启ambari中的所有服务。  结果5分钟过去后, 发现namenode以及后面的什么 hbasemaster等都无法启动。 尝试不断重启等操作后无果。

2.细下心来看日志。首先看namenode相关的日志,

关键日志如下:

WARN org.apache.hadoop.hdfs.qjournal.client.QuorumJournalManager: Waited 96070 ms (timeout=120000 ms) for a response for getJournalState(). Succeeded so far: [XXX.XXX.XXX.XXX:8485]

发现是写journalnode 出错。 一直在等待。

看journalnode的3个节点是启动成功的,看journalnode的日志也是正常的。 后面各种尝试,始终卡在这里。

3. 后来偶然想到会不会由于集群中的各个节点磁盘空间并不是同时占满,那有可能就是数据完整性的问题, datanode中的数据丢失不会导致namenode启动问题。那就只剩下namenode中的元数据了, 分别看各个journalnode的 元数据目录 

/hadoop/hdfs/journal/mycluster/current

统计文件个数:

ls /hadoop/hdfs/journal/mycluster/current/ | wc -l

发现有一个journalnode的个数和其它两个不一样。   果断去有问题的节点, 删除原文件夹, 再重启journalnode的所有节点

4.再次重启namenode  发现报错不一样了, 报

No live collector to send metrics to

这个简单, 是Metrics Collector 没启动成功导致的。

5. 启动Metrics Collector  发现它卡在hbase:meta相关表那里, 此时hbase还没启动成功, 果断删除 Metrics的数据 (也可以备份一下)

rm -rf /var/lib/ambari-metrics-collector/*

6.再重启 Metrics Collector    成功

7.重启namenode 成功

8.重启datanode 成功

9.重启hbase相关  结束。

ambari-server迁移

在新的ambari-server 安装  ambari-server
设置java环境
系统基础设置
设置与各个节点之间的ssh免密码登陆
ssh-copy-id -i /root/.ssh/id_rsa.pub datanodeyy-37.ds.xx.cn
ssh-copy-id -i /root/.ssh/id_rsa.pub datanodeyy-xxx.ds.xx.cn
…..  节点太多估计要多花点时间
各个节点的hosts文件要把新的ambari-server 主机名与ip信息添加进去    #节点太多估计要多花点时间   最好用内部DNS服务器就会省事很多 
添加repo库
 [ambari]
name=ambari
baseurl=http://172.16.30.22/AMBARI-2.2.1.0/centos7/2.2.1.0-161/
gpgcheck=0
enabled=1

yum install ambari-server
复杂mysql java连接jar包
cp mysql-connector-java-5.1.34.jar /usr/share/java/mysql-connector-java-5.1.34.jar
cp mysql-connector-java-5.1.34.jar /usr/lib/ambari-server/mysql-connector-java-5.1.34.jar

直接重用原来ambari-server的配置文件
mv /etc/ambari-server/conf  /etc/ambari-server/confold
scp -r root@old.ambari-server.xx.cn:/etc/ambari-server/conf /etc/ambari-server/conf

然后直接就启动ambari-server
ambari-server   start  (因为直接用了原有的配置文件,就不用ambari-server setup了  注意java环境路径,基础环境要跟原来的一样,不然会出错)

直接 https://ambari-serverxxxx.cn:8080     admin/admin  就直接进去了,  但是进去由于ambari-agent没有修改,故会发现所有节点都是丢失心跳状态

修改各个节点的ambari-agent
把/etc/ambari-agent/conf/ambari-agent.ini  中的
hostname=old-ambari-server
改为
hostname=new-ambari-server

重启agent
ambari-agent restart       #节点太多建议用ansiable跑一下就省事很多

over

redis mark

config set client-output-buffer-limit “slave 0 0 0” #防止全量同步时 生成的实例快照过大造成同步失败
config set repl-backlog-size 936870912 #建议时间长一点,全量备份恢复时间过长,主中的临时写入队列放里面,太短的话,可能造成无限的全量同步
config set repl-timeout 240    #建议时间长一点,全量备份恢复时间过长,造成判断为集群断开,造成无限的全量同步,
config set no-appendfsync-on-rewrite yes   #做bgrewriteaof的时候 就不要再主动往 aof文件中追加, 会造成文件Io争抢,造成阻塞. 仅会造成一点点的数据安全隐患,可接受范围
config set appendfsync “no”  #性能最高。由于集群由主从两份,30s的数据安全可保证
config set stop-writes-on-bgsave-error no   #bgsave失败就不允许再写入 这开关关闭影响比较小

config set save “”  #aof 和RDB 选一个就好

echo 1 > /proc/sys/vm/overcommit_memory  # vm.overcommit_memory=1
echo 511 > /proc/sys/net/core/somaxconn
echo never > /sys/kernel/mm/transparent_hugepage/enabled  #redis的页单位的数据量是比较小的,启用大页不方便管理
/etc/security/limits.conf   #ulimit 限制 65535

cluster failover  #手动切换redis cluster的主从关系  后面可加force 强制选项

redis-trib.rb  create  –replicas 1  192.168.1.101:6379  192.168.1.102:6379   192.168.1.103:6379   192.168.1.104:6379   192.168.1.105:6379   192.168.1.106:6379 #create 创建集群  replicas  代表有几个备份
redis-trib.rb add-node 192.168.0.110:6379  192.168.0.120:6379 #增加集群节点

在做bgrewriteaof 太慢失败时, 可先尝试做一次bgsave 再做bgrewriteaof 就会快很多

chrome调试

#跳过https 证书 不安全检查

在chrome该页面上,直接键盘敲入这11个字符:thisisunsafe

console中 输出对应DOM的值
$0 返回最后一次点选的DOM节点
先选中对应的DOM节点 再
$0.value

$0~$4则代表了最近5个你选择过的DOM节点。

也可以使用 类似 document.getElementById(‘ext-co-1543’).value;

copy通过此命令可以将在控制台获取到的内容复制到剪贴板
copy($0)
copy(document.body)

monitor & unmonitor
monitor(function),它接收一个函数名作为参数,比如function a,每次a被执行了,都会在控制台输出一条信息,里面包含了函数的名称a及执行时所传入的参数。
而unmonitor(function)便是用来停止这一监听。

console中关于类似jquery选择器的支持:

1. 如果打开的网页本身使用了jQuery,那么它的控制台是可以直接使用所有的jQuery语法的(具体根据jQuery版本而定)。 
2. chrome浏览器的控制台支持一部分jQuery的语法(jq选择器),并非全部。
若网页本身中没有包含jquery,则可以

先添加这两个chrome扩展
jQuery Injector
jQuery Everywhere   没用

直接注入jquery代码由于chrome CSP安全原因,下面这两种办法引入jquery 无用

var importJs=document.createElement('script')  //在页面新建一个script标签
importJs.setAttribute("type","text/javascript")  //给script标签增加type属性
importJs.setAttribute("src", 'http://ajax.microsoft.com/ajax/jquery/jquery-1.4.min.js') //给script标签增加src属性, url地址为cdn公共库里的
document.getElementsByTagName("head")[0].appendChild(importJs) //把importJs标签添加在页面
;(function(d,s){d.body.appendChild(s=d.createElement('script')).src='http://cdn.bootcss.com/jquery/1.11.0/jquery.min.js'})(document);

// https页面先在控制台写如下代码
;(function(d,s){d.body.appendChild(s=d.createElement('script')).src='https://cdn.bootcss.com/jquery/1.11.0/jquery.min.js'})(document);


js断点中,在wath中直接修改js变量值

sql mark

1.查看抢占锁的语句

SELECT * FROM information_schema.innodb_trx where trx_id in (SELECT lock_trx_id FROM information_schema.INNODB_LOCKS WHERE LOCK_TRX_ID IN (SELECT BLOCKING_TRX_ID FROM information_schema.INNODB_LOCK_WAITS) );

php jwt

1.生成签名:

<?php
$message="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczpcL1wveHh4eC54eHguY25cL3dhcFwvaW5kZXgucGhwIiwidWlkIjoieHh4eCIsImNpdHkiOiJ4eHgiLCJkYXRhX3ZlciI6MiwidHMiOjE1MzcxNzg5NjE5MzEsImNpdHlfY29kZSI6IjUwMDEwMCIsInByb3ZfY29kZSI6IjUwMDAwMCIsInByb3YiOiJ4IiwibGF0IjoyMTkuNjE0NTE1ODA2OTU5MTA1LCJsbmciOjIwNi41MDYyNTMyODI0MzMxMSwibm9uY2UiOiI2QTAyMkI5MS1BRUQ1LTQ3N0MtODkzRC1BODQ3RDkyMjk1RUEifQ==";
$secret='07e4e10fbc774f8ab914b58a2ea26752';
$secret=md5($secret);
$s = hash_hmac('sha256', $message, $secret,true);
$resut=base64_encode($s);
echo $resut;
$saferesult=str_replace('=', '', strtr(base64_encode($s), '+/', '-_'));
var_dump($saferesult);
?>

2.

<?php
$head='{"alg": "HS256","typ": "JWT"}';
$payload='{"sub": "1234567890","name": "John Doe","iat": 151623902}';
$head_base=base64_encode($head);
$payload_base=base64_encode($payload);
$message="{$head_base}.{$payload_base}";
$secret='07e4e10fbc774f8ab914b58a2ea26752';
//$secret=md5($secret);
$s = hash_hmac('sha256', $message, $secret,true);
$resut=base64_encode($s);
echo $resut;
$saferesult=str_replace('=', '', strtr(base64_encode($s), '+/', '-_'));
var_dump($saferesult);
$token=$message.".".$saferesult;
?>

lua dump 变量

function var_dump(data, max_level, prefix)   
	if type(prefix) ~= "string" then   
		prefix = ""  
	end   
	if type(data) ~= "table" then   
		dump_html(prefix .. tostring(data))   
	else  
		dump_html(tostring(data))   
		if max_level ~= 0 then   
			local prefix_next = prefix .. "    "  
			dump_html(prefix .. "{")   
			for k,v in pairs(data) do   
				dump_html(prefix_next .. k .. " = ") 
				if type(v) ~= "table" or (type(max_level) == "number" and max_level <= 1) then   
					dump_html(v)   
				else  
					if max_level == nil then   
						var_dump(v, nil, prefix_next)   
					else  
						var_dump(v, max_level - 1, prefix_next)   
					end   
				end   
			end   
			dump_html(prefix .. "}")   
		end   
	end   
end  


function dump_html(str)
	if str ~= nil then
		ngx.header.content_type = "text/html"
        ngx.say(str)
	end
end

logstash 解析nginx error日志

input {
#    beats {
#        host => "0.0.0.0"
#        port => 5400
#    }

stdin { }
}

filter {
 grok {
   patterns_dir => "/etc/logstash/patterns"
   #match => [ "message" , "%{NGINXACCESS}"]
   match => [ "message" , "%{DATA:timestr} \[%{DATA:error_level}\] (?<nginx_message>(.|\r|\n)*)(?:, client: %{IPORHOST:clientip})(?:, server: %{IPORHOST:nginx_server})(?:, request: \"%{DATA:nginx_request}\")?(?:, upstream: \"%{DATA:nginx_upstream}\")?(?:, host: \"%{DATA:nginx_host}\")?(?:, referrer: \"%{DATA:nginx_referrer}\")?"]
 }

      if [http_x_forwarded_for] == "-" or [http_x_forwarded_for] == "null" {
         mutate {
            update => { "http_x_forwarded_for" => "" }
         }
      }

      if [referer] == "-" or [referer] == "null" {
         mutate {
            update => { "referer" => "" }
         }
      }

    geoip {
      source => "clientip"
    }

    useragent {
      source => "agent"
      target => "agent_fields"
    }

  date {
    match => [ "timestr", "yyyy/MM/dd HH:mm:ss" ]
    timezone => "Asia/Shanghai"
    #target => "newtimestr"
    #locale => "en"
  }

        ruby {
                code => "event.set('index_day', event.get('@timestamp').time.localtime.strftime('%Y%m%d'))"
        }


}

output {
 elasticsearch {
   hosts => ["127.0.0.1:9200"]
   #index => "tek-%{+YYYY.MM.dd}"
   index => "tek-%{index_day}"
   document_type => "nginx_logs"
   template_name => "ta"
 }
 stdout { codec => rubydebug }
}

防止一天的日志分在了两个index中

        ruby {
                code => "event.set('index_day', event.get('@timestamp').time.localtime.strftime('%Y%m%d'))"
        }