小五博客 //www.lcvmw.cn 编程开发,大数据研究学习,搜索营销,SEO,搜索引擎优化 Tue, 14 Aug 2018 05:26:24 +0000 zh-CN hourly 1 谨慎安装Python3.7.0,SSL低版本导致Pip无法使用 //www.lcvmw.cn/daily/4176.html //www.lcvmw.cn/daily/4176.html#respond Tue, 14 Aug 2018 05:26:24 +0000 //www.lcvmw.cn/?p=4176 ?

最新新配置了一台服务器。安装 的时候直接使用了最新的Python 3.7最新版本。

?

安装成功,编译成功。但是用pip 安装包的时候提示:pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available。

?

已经习惯了用pip安装各种包,突然不能用,还是非常 不习惯 。果断寻找解决方案。

?

搜索了一些资料,发现原因是python3.7为了安全性考虑,要求使用openssl 1.0.2之后的版本。但是服务器安装的时候,版本是1.0.1。

?

openssl是什么东西可以百度一下,其实就是加密传输相关的一些基础库。但是在Linux里面广泛使用。几乎所有的服务器都需要它支持。

?

可以通过openssl version查看SSL库版本号。

?

于是想到升级OpenSSL。此处坑来了。yum安装这些基础库最简单快捷,但是包括阿里云最新的yum镜像里面,也是使用的1.0.1的openssl。所以用yum 是无法升级的,需要手动编译。

?

于是安装最新的1.0.2希望能解决这个问题:

wget //www.openssl.org/source/openssl-1.0.2j.tar.gz
tar -xzf openssl-1.0.2j.tar.gz
cd openssl-1.0.2j
./config
./config -t
make
make install
openssl version #查看版本

编译成功也能正常使用,但是pip依然不能使用,需要重装Python。于是

wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tar.xz
tar -xvJf Python-3.7.0.tar.xz
cd Python-3.7.0
./configure --with-ssl --enable-optimizations --with-openssl=/usr/local/openssl
make && make install

还是失败。于是在Make的时候仔细看了一下,发现另有错误信息。

Could not build the ssl module!
Python requires an OpenSSL 1.0.2 or 1.1 compatible libssl with X509_VERIFY_PARAM_set1_host().
LibreSSL 2.6.4 and earlier do not provide the necessary APIs, https://github.com/libressl-portable/portable/issues/381

?

还是找不到openssl 1.0.2。不知道是不是编译的流程有问题。按理说最简单的包应该没有什么问题。估计问题出在openssl安装好了之后,相关的系统的lib库没有更新。

?

于是继续搜索了一次。发现如果安装Open SSL 1.0.2。某些程序会报错?;褂兴蛋沧皁penssl的时候,安装配置需要改

./config

改为

./config shared zlib?

由于要赶时间使用。所以先用了简单方案?;换豍ython3.6.6使用。

安装方法:

wget https://www.python.org/ftp/python/3.6.6/Python-3.6.6.tgz
tar xzf Python-3.6.6.tgz
cd Python-3.6.6
./configure --enable-optimizations

make
make install

?

然后使用

curl https://bootstrap.pypa.io/get-pip.py | python3

安装pip,之后可以正常使用。

?

后续又搜索了一下安装和升级Openssl的方法。

1、安装依赖

yum install -y zlib

?

2、编译和安装

wget //www.openssl.org/source/openssl-1.0.2j.tar.gz
tar -xzf openssl-1.0.2j.tar.gz
cd openssl-1.0.2j
./config shared zlib

./config -t
make
make install
openssl version #查看版本

mv /usr/bin/openssl /usr/bin/openssl.bak
mv /usr/include/openssl /usr/include/openssl.bak
ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/ssl/include/openssl /usr/include/openssl

#配置库文件搜索路径
echo "/usr/local/ssl/lib" >> /etc/ld.so.conf
ldconfig -v

?

但是没有进行一波测试。因为线上已经使用python3.6在跑服务了。

理论上应该可行。

?

另外有意思的是python3.7官方推荐使用LibRessl进行SSL加密传输

https://www.libressl.org/

?

但是却没有相关的文档 ,怎么编译到python3.7里面?;故撬抵苯影沧傲司突嶙远褂胠ibressl,尚未可知。

?

?

?

?

?

?

?

声明: 本文采用 BY-NC-SA 协议进行授权 | 盛世北京赛车pk10历史记录
转载请注明转自《谨慎安装Python3.7.0,SSL低版本导致Pip无法使用

]]>
//www.lcvmw.cn/daily/4176.html/feed 0
Python使用pandas处理数据时replace替换失效 //www.lcvmw.cn/daily/4175.html //www.lcvmw.cn/daily/4175.html#respond Sat, 28 Jul 2018 04:33:03 +0000 //www.lcvmw.cn/?p=4175 ?

最近在使用Pandas进行数据处理的时候,发现从CSV里面读取出来的内容,带了一些\t字符,想要进行替换。

?

网上通用的做法是像下面这样的代码:

df["交易类型"] = df["交易类型"].replace("\\t", '')

?

最后试了一下,死活替换不了,国内国外搜索了大量的资料,也没有解决。所以打印一下头部

df.head(5)

发现数据类型是object对象:Name: 交易类型, dtype: object

感觉有点问题。字符串不应该是str类型吗。难道说python里面没有str这种数据类型。

?

然后果断搜索了一下。终于发现有人使用了另一种方式替换数据。

col1=dfxA_2['travel_seq'].str.split('#').str[0]

?

马上回过头了,知道怎么解决了。果断一试。

代码:

df["交易类型"] = df["交易类型"].str.replace("\\t", '')

?

果断成功。

?

Pandas真是python处理数据里面的神器工具,强大的功能,在做数据预处理的时候,异常方便快捷。

像读取一个CSV和Excel文件,都是一行代码解决(data = pd.read_csv('fee.csv', encoding='gbk', sep=',’))

?

推荐有兴趣的把玩一下。

?

近来发现多种语言配合开发,可以达到非??晒鄣目⑿?。

?

处理数据用python。稳定的复杂的一些东西用java。网站用php。真是非常爽快。

?

?

?

?

声明: 本文采用 BY-NC-SA 协议进行授权 | 盛世北京赛车pk10历史记录
转载请注明转自《Python使用pandas处理数据时replace替换失效

]]>
//www.lcvmw.cn/daily/4175.html/feed 0
我又回来了~ //www.lcvmw.cn/daily/4174.html //www.lcvmw.cn/daily/4174.html#respond Fri, 27 Jul 2018 15:59:22 +0000 //www.lcvmw.cn/?p=4174 ?

年前因为工作的原因,去搞了一段时间的Java。

?

搞了半年项目,天天加班,实在不想苦逼了。最近正在离职。应该有时间继续写博了。

?

最近把python和java都搞了一遍。有些经验有机会再分享。

声明: 本文采用 BY-NC-SA 协议进行授权 | 盛世北京赛车pk10历史记录
转载请注明转自《我又回来了~

]]>
//www.lcvmw.cn/daily/4174.html/feed 0
Java跨域经验一则 //www.lcvmw.cn/yunwei/nginx/4172.html //www.lcvmw.cn/yunwei/nginx/4172.html#respond Mon, 18 Dec 2017 02:50:11 +0000 //www.lcvmw.cn/?p=4172 ?

最近开发了一个Java的后端小程序,在微信小程序这边使用Web-view进行HTML5的嵌套,然后用Ajax进行接口的调用。后端的接口使用Java的格式进行返回。

?

然后,使用postman进行请求能正常返回,使用HTML却无法得到结果。料想应该是浏览器的跨域问题。

?

然后添加一段SpringBoot的代码解决全局所有域名的跨域调用。

?

代码如下:

/**
* CORS全局统一跨域设置,所有均可跨域
*/
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}

@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}

?

这段代码过于粗暴,无法控制跨域的请求域名,还可以通过CrosFilter的形式进行自定义设置,还在研究中。

?

顺手找了一段HTML用于测试跨域问题是否存在。存档备用。cros_test.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>跨域测试</title>
<script src="//apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
function crosRequest() {
$.ajax({
url: '//112.111.1.1:8092/api/v1/getHotList',
type: 'post',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
source: 'baidu',
category: 'index'
}),
success: function (data) {
console.log(data);
}
});
}
</script>
</head>
<body>
<button onclick="crosRequest()">请求跨域资源</button>
</body>
</html>

?

核心点在于加上JSON.stringify,才能以POST JSON的形式提交Java后端。

然后在Console里面可以看到是否是跨域的问题造成的无法请求。

?

另:在测试跨域的时候,cros_test.html不要放到接口同域下面,否则测试不了,可以本地使用hosts建一个虚拟空间,配合Nginx把cros_test.html放到a.com下面,然后接口访问b.com的接口,才能测试出是否有跨域的问题。

?

?

?

?

?

声明: 本文采用 BY-NC-SA 协议进行授权 | 盛世北京赛车pk10历史记录
转载请注明转自《Java跨域经验一则

]]>
//www.lcvmw.cn/yunwei/nginx/4172.html/feed 0
测试新的WordPress编辑工具 //www.lcvmw.cn/daily/4171.html //www.lcvmw.cn/daily/4171.html#respond Thu, 07 Dec 2017 10:41:54 +0000 //www.lcvmw.cn/?p=4171 ?

新换了一个编辑工具MarsEdit,测试一下效果怎么样,太久没更新了,要准备开始更新内容了。

?

?

测试。。。

声明: 本文采用 BY-NC-SA 协议进行授权 | 盛世北京赛车pk10历史记录
转载请注明转自《测试新的WordPress编辑工具

]]>
//www.lcvmw.cn/daily/4171.html/feed 0
Shell自动备份Gitlab仓库的数据 //www.lcvmw.cn/yunwei/4170.html //www.lcvmw.cn/yunwei/4170.html#respond Wed, 02 Aug 2017 08:02:47 +0000 //www.lcvmw.cn/?p=4170  

很久没有更新了,抽时间快速整理一小段代码。

 

公司的Gitlab我在管理,一直没有时间做自动备份,生怕哪天出问题就完蛋了。

 

Gitlab自带有备份的功能,使用:

gitlab-rake gitlab:backup:create

即可在目录

/var/opt/gitlab/backups/下面生成备份的文件。

 

现在快速弄一个简单的Shell,做每天的自动备份以及历史备份的清理。

 

#!/bin/bash
#
# add to crontab :0 5 * * sh /data/scripts/backup_gitlab.sh
#

echo 'begin backup gitlab'

/opt/gitlab/bin/gitlab-rake gitlab:backup:create

echo 'Backp down! Begin copy to new folder'

# copy file created inner 60 minutes to backup folder
find "/var/opt/gitlab/backups/" -name "*.tar" -cmin -60 -type f -exec cp -R {} /data/backup/ \;

# delete old 2 day file
find "/var/opt/gitlab/backups/" -name "*.tar" -ctime +2 -type f -exec rm -rf {} \;

# delete 7 day files
find "/data/backup/" -name "*.tar" -ctime +7 -type f -exec rm -rf {} \;

echo 'backup gitlab work done'

主要用到的几个Find命令。

第一个-cmin –60 指60分钟以内创建的文件进行搜索

-ctime +2 指2天以前创建的文件

同理+7 代表7天以前创建的文件。

 

最后的逻辑是这样的:

1、备份

2、复制到/data/backup/目录统一管理

3、清理git自身目录2天以前的备份文件

4、清理backup目录7天以前的文件,因为我是每天备份,相当于保留7天数据。

 

然后chmod +x backup_git.sh 设置脚本具有执行权限。

放到目录/data/scripts下面。

 

使用crontab -e编辑定时任务

末尾加上:

0 5 * * * sh /data/scripts/backup_gitlab.sh

 

保存之后/etc/init.d/crond restart重启定时任务。

 

好了。以后每天凌晨5点会自动进行备份,并清理数据,如果有需要传到远程,再加上代码就Over了。

声明: 本文采用 BY-NC-SA 协议进行授权 | 盛世北京赛车pk10历史记录
转载请注明转自《Shell自动备份Gitlab仓库的数据

]]>
//www.lcvmw.cn/yunwei/4170.html/feed 0
记一次LNMP 1.4环境运行Lavavel5.2发布Nginx空白页面异常 //www.lcvmw.cn/sitebuild/laravel/4168.html //www.lcvmw.cn/sitebuild/laravel/4168.html#respond Sun, 11 Jun 2017 14:25:09 +0000 //www.lcvmw.cn/?p=4168  

本地运行的Larave一切正常,LNMP发布了最新的1.4版,以往一直使用这个做为Web环境,于是立即在服务器重新布署安装用上了。

 

自带的phpmyadmin什么的一切正常。传上Laravel之后,打开页面,确是空白的。

 

Nginx没有捕捉到错误信息,Laravel也没有任何错误日志记录,这就非常奇怪了。

 

于在在laravel目录/public/index.php这个入口文件的最开头加上echo ‘test1’;,结尾最后一行加上echo ‘test2’;

 

发现test1执行了,test2没执行,想能可能是Laravel没启动。

 

于是想再打开更明细的日志,看问题可能是什么地方,打开Nginx.conf配置,把开头的

error_log  /home/wwwlogs/nginx_error.log  crit;

 

改为info。这样会记录下绝大多数错误信息。

 

重启nginx之后,在日志里面终于找到了错误原因:

*31 FastCGI sent in stderr: "PHP message: PHP Warning:  require(): open_basedir restriction in effect. File(/data/test.cn/path.php) is not within the allowed path(s): (/data/test.cn/public/:/tmp/:/proc/) in /data/car3.cn/public/index.php on line 10

 

原来是php设置了路径限制,以确保程序安全。我用的这个laravel是经过自己改装的,会引用公共的系统文件,不知道原生的是否也会有这个问题。

 

打开Nginx的虚拟主机配置文件,在/usr/local/nginx/conf/vhost/域名.conf下面。

 

看到只有一个enable-php.conf,再打开enable-php.conf,再发现一个fastcgi.conf的引用。

在最后终于找到的配置所在:

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/tmp/:/proc/";

 

由于安全性的考虑,在安装的时候会自动打开这处安装限制,禁止程序跨目录引用另外的文件。

 

在一些框架里面,常常有跨目录引用。才会造成这处错误。

 

于是注释 第二行带openbasedir的。重启整个lnmp ,lnmp restart。

 

再访问页面,一切正常。。。

 

 

然后把nginx的错误日志还原为crit,否则info的方式,会记录非常非常多的垃圾日志出来。

 

LNMP是个非常非常好用的web环境,下载回本地之后,还可以增加多处自定义配置, 但是日常使用的时候,也不一定能满足定制化的需求 。

 

一定要学会发现问题,才能最好的解决问题。多思考问题和出路。

声明: 本文采用 BY-NC-SA 协议进行授权 | 盛世北京赛车pk10历史记录
转载请注明转自《记一次LNMP 1.4环境运行Lavavel5.2发布Nginx空白页面异常

]]>
//www.lcvmw.cn/sitebuild/laravel/4168.html/feed 0
Python多线程写文件的2种方案 //www.lcvmw.cn/coding/4166.html //www.lcvmw.cn/coding/4166.html#respond Wed, 10 May 2017 09:30:46 +0000 //www.lcvmw.cn/?p=4166 最近帮同事写一个批量查询数据的脚本。

从一个几十万行的文件内,读取第一行,查每一行是否收录。

单线程下面,效率非常低。

检查发现主要在请求网络时非常 慢。采用多线程之后,写文件到日志 里面成了最大的问题。

 

搜索了一下发现python并没有比较合适的并发写文件的示例。

 

参考了一些资料 ,总结出如下2种写法:

 

1、使用python的logging库。

自定义配置。需要做2步设置

首先使用cloghandler.ConcurrentRotatingFileHandler做为文件写出工具。需要sudo pip install ConcurrentLogHandler先安装再使用。。

然后把日志输出的格式改为format=%(message)s

除了信息不要任何东西。

 

然后并发时,使用

logging.config.fileConfig('logging.conf')
logger = logging.getLogger(__name__)

线程内使用:

logger.info(line.strip() + "," + htmlResult)

即可并发输出,效率有明显提升。

 

2、使用resultqueue = Queue.Queue()

多线程里面,取出每行URL,不停的请求页面,获取结果,把结果往resultqueue里面不停的写内容。

 

另开一个子线程读取resultqueue里面的内容,单线程循环写到文件内。单线程写文件速度还是非???,避免了多线程同时操作文件的问题。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 把queue队列里面的内容循环取出来写到文件,单个线程去操作
class WriteFileThread(threading.Thread):
?   def __init__(self, queue):
?       threading.Thread.__init__(self)
?       self.queue = queue

?   def run(self):

?       output = codecs.open('result.txt', 'w')

?       emptyCount = 0
?       while True:

?           if emptyCount > 20:
?               print '连续20次没有数据可获取,自动结束队列了'
?               break

?           # 如果队列为空,标记为空
?           if (self.queue.empty()):
?               emptyCount += 1  # 为空次数加1
?               print "队列为空,第%s次休息,2秒再检查" % emptyCount
?               time.sleep(2)  # 休息2秒

?           else:
?               emptyCount = 0  # 只要队列不是空的,就重置这个等待次数,以防断断续续导致提前退出
?               result = self.queue.get()

?               print '从队列获取到结果:' + result
?               output.write(result + "\r\n")  # 从队列里面读取出来的结果直接写到文件里面

?               # self.queue.task_done()

?       self.queue.task_done()
?       print "结束任务,写入文件关闭 At 【%s】" % time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
?       output.close()

刚用python,代码粗漏。

3、把queue换成redis,更好用。

 

声明: 本文采用 BY-NC-SA 协议进行授权 | 盛世北京赛车pk10历史记录
转载请注明转自《Python多线程写文件的2种方案

]]>
//www.lcvmw.cn/coding/4166.html/feed 0
Java使用Jedis操作Redis并发时遇到的坑记录 //www.lcvmw.cn/coding/java/4163.html //www.lcvmw.cn/coding/java/4163.html#respond Wed, 12 Apr 2017 10:23:33 +0000 //www.lcvmw.cn/?p=4163  

Java在使用jedis操作redis数据时,遇到坑,各种查资料解决了将近1天才实现结果。

 

坑1:

直接在Idea里面,建TestNG的Test类时,

里面的多线程代码,一直会提示报错,没有任何提示,直接就test任务结束。

解决方案:使用main建入口的方式进行测试,千万不要使用testng的@Test注解这种方式进行测试。

 

原因,估计是多线程引起的。怎么弄还不明白,只能换成main方法里面去执行多线程。

 

坑2:

多线程并发会造成冲突,会报各种错。

 

解决方法:使用JRedisPool建立线程池。

 

而且在操作时,使用synchronized把操作方法进行封装。否则依然会报错。

 

坑3:

超出线程池容量。1000个线程,会报大量的错。

 

解决方法:

JedisPoolConfig里面设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
setMaxTotal为1000,即可以连接的最大数量。


然后并发1000个线程都可以操作Redis了。完美。

大概的代码:

public class JedisUtils {

?   protected static Logger logger = LoggerFactory.getLogger(JedisUtils.class);

?   //Redis服务器IP
?   private static String ADDR_ARRAY = "127.0.0.1";

?   //Redis的端口号
?   private static int PORT = 6379;

?   //访问密码
?   private static String AUTH = "";

?   //可用连接实例的最大数目,默认值为8;
?   //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
?   private static int MAX_ACTIVE = 500;

?   //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
?   private static int MAX_IDLE = 100;

?   //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
?   private static int MAX_WAIT = 10 * 1000;

?   private static int TIMEOUT = 10 * 1000;//超时时间

?   //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
?   private static boolean TEST_ON_BORROW = true;

?   private static JedisPool jedisPool = null;

?   /**
?    * 初始化Redis连接池
?    */
?   private static void initialPool() {
?       try {
?           JedisPoolConfig config = new JedisPoolConfig();
?           config.setMaxTotal(MAX_ACTIVE);
?           config.setMaxIdle(MAX_IDLE);
?           config.setMaxWaitMillis(MAX_WAIT);

?           config.setTestOnBorrow(TEST_ON_BORROW);//使用时进行扫描,确保都可用

?           config.setTestWhileIdle(true);//Idle时进行连接扫描

?           config.setTestOnReturn(true);//还回线程池时进行扫描
//
////表示idle object evitor两次扫描之间要sleep的毫秒数
//            config.setTimeBetweenEvictionRunsMillis(30000);
//
////表示idle object evitor每次扫描的最多的对象数
//            config.setNumTestsPerEvictionRun(10);
//
////表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
//            config.setMinEvictableIdleTimeMillis(60000);

?           if (StringUtils.isNotBlank(AUTH)) {
?               jedisPool = new JedisPool(config, ADDR_ARRAY.split(",")[0], PORT, TIMEOUT, AUTH);
?           } else {
?               jedisPool = new JedisPool(config, ADDR_ARRAY.split(",")[0], PORT, TIMEOUT);
?           }

?       } catch (Exception e) {
?           logger.error("First create JedisPool error : " + e);
?           try {
?               //如果第一个IP异常,则访问第二个IP
?               JedisPoolConfig config = new JedisPoolConfig();
?               config.setMaxTotal(MAX_ACTIVE);
?               config.setMaxIdle(MAX_IDLE);
?               config.setMaxWaitMillis(MAX_WAIT);
?               config.setTestOnBorrow(TEST_ON_BORROW);
?               jedisPool = new JedisPool(config, ADDR_ARRAY.split(",")[1], PORT, TIMEOUT, AUTH);
?           } catch (Exception e2) {
?               logger.error("Second create JedisPool error : " + e2);
?           }
?       }
?   }

?   /**
?    * 在多线程环境同步初始化
?    */
?   private static synchronized void poolInit() {
?       if (jedisPool == null) {
?           initialPool();
?       }
?   }


?   /**
?    * 同步获取Jedis实例
?    *
?    * @return Jedis
?    */
?   public synchronized static Jedis getJedis() {
?       if (jedisPool == null) {
?           poolInit();
?       }

?       Jedis jedis = null;
?       try {
?           if (jedisPool != null) {
?               jedis = jedisPool.getResource();
?           }
?       } catch (Exception e) {
?           logger.error("Get jedis Error : " + e.getMessage(), e);
?       } finally {
?           returnResource(jedis);//归还到Redis池里面
?       }
?       return jedis;
?   }

?   /**
?    * 释放jedis资源
?    *
?    * @param jedis
?    */
?   public static void returnResource(final Jedis jedis) {
?       if (jedis != null && jedisPool != null) {
?           jedisPool.returnResource(jedis);
?       }
?   }

?   /**
?    * 关闭连接池
?    */
?   public static void closePool() {
?       if (jedisPool != null) {
?           jedisPool.close();
?       }
?   }

?   /**
?    * 设置 String
?    *
?    * @param key
?    * @param value
?    */
?   public synchronized static void setString(String key, String value) {
?       try {
?           value = StringUtils.isEmpty(value) ? "" : value;
?           getJedis().set(key, value);
?       } catch (Exception e) {
?           logger.error("Set key error : " + e);
?       }
?   }

?   /**
?    * 设置 过期时间
?    *
?    * @param key
?    * @param seconds 以秒为单位
?    * @param value
?    */
?   public synchronized static void setString(String key, int seconds, String value) {
?       try {
?           value = StringUtils.isEmpty(value) ? "" : value;
?           getJedis().setex(key, seconds, value);
?       } catch (Exception e) {
?           logger.error("Set keyex error : " + e);
?       }
?   }

?   /**
?    * 获取String值
?    *
?    * @param key
?    * @return value
?    */
?   public synchronized static String getString(String key) {
?       if (getJedis() == null || !getJedis().exists(key)) {
?           return null;
?       }
?       return getJedis().get(key);
?   }

}

 

 

 

声明: 本文采用 BY-NC-SA 协议进行授权 | 盛世北京赛车pk10历史记录
转载请注明转自《Java使用Jedis操作Redis并发时遇到的坑记录

]]>
//www.lcvmw.cn/coding/java/4163.html/feed 0
php Laravel5.2框架遇到的小问题 //www.lcvmw.cn/coding/php/4161.html //www.lcvmw.cn/coding/php/4161.html#respond Wed, 15 Feb 2017 07:11:59 +0000 //www.lcvmw.cn/?p=4161  

Laravel是我的神器之一,最近升级到5.2,又是新增了非常多的特性。

 

写代码的遇到习惯性的写了一个有问题的代码出来

 

Larave使用Model查询一般有2种大概的查询写法:

Collect::find($collectId);根据ID直接查

另一种是Collect::where(‘id’,$collectId)->first();

 

写的时候不小心写成了Collect::find($collectId)->first();

 

这个写法是错误的,但是并没有报异常,日志也没有记录。后来不注意才发现这个错误写法。

 

但是返回的并不是这个ID的结果,直接查出来数据库的第一条结果。这种写法本身应该是有冲突的。

 

但是Laravel的链式操作并没有弄清楚,也没报错。

 

一般遇到解决不了的问题,我会打开Laravel的监听器,监听SQL查询语句,以便定位问题所在。以后有机会再分享。

声明: 本文采用 BY-NC-SA 协议进行授权 | 盛世北京赛车pk10历史记录
转载请注明转自《php Laravel5.2框架遇到的小问题

]]>
//www.lcvmw.cn/coding/php/4161.html/feed 0
北京pk10计划软件 |