As the title, I'm looking for a php Redis client that support persistent connection, because my web application receives a lot of requests(each request, it'll put an item in to Redis queue) and I want to avoid create new connection every request.
Not sure if this is supported but you should definitely look at Predis and Rediska, this two (especially Predis AFAIK) are the best PHP Redis clients available.
PhpRedis currently supports persistent connections. Using PHP 7.0 and PhpRedis 3.0, making a persistent connection with pconnect() like this:
for ($i=0;$i<1000;$i++) {
$redis = new Redis();
$result = $redis->pconnect('127.0.0.1');
$redis->set("iterator",$i);
$response=$redis->get("iterator");
$redis->close();
unset($redis);
}
is about 10 times faster (9.6 msec vs 0.83 msec per connection) than connect():
for ($i=0;$i<1000;$i++) {
$redis = new Redis();
$result = $redis->connect('127.0.0.1');
$redis->set("iterator",$i);
$response=$redis->get("iterator");
$redis->close();
unset($redis);
}
Note: "This feature is not available in threaded versions". (I'm running under IIS on Windows, so I run the NTS version.)
Predis supports persistent connection. you just need to add persistent paramater as 1.
you can use the code below
$client = new Predis\Client(array(
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'database' => 15,
'persistent'=> 1
));
instead of
$client = new Predis\Client('tcp://127.0.0.1:6379?database=15');
you can find more parameters for the connection here :
https://github.com/nrk/predis/wiki/Connection-Parameters
Predis supports persistent connections using it's PhpiredisStreamConnection with the persistent=1 flag syntax since v0.8.0:
<?php
$client = new Predis\Client('tcp://127.0.0.1?persistent=1', array(
'connections' => array(
'tcp' => 'Predis\Connection\PhpiredisStreamConnection',
'unix' => 'Predis\Connection\PhpiredisStreamConnection',
),
);
PHP-Redis supports persistent connections since it uses a php extension written in C which gives it a mechanism for sharing connections between requests. Look at the documentation on popen and pconnect.
Predis cannot support persistent connections because it is 100% PHP and PHP shares nothing between each request.
Related
I have a PHP Laravel (5.6) system that I need to connect to an FTP server to upload a single file. The FTP server that I am connecting to is restricting access by ip address, uses port 990, and other than that has a seemingly simple configuration. On my local machine (I'm running on Linux Ubuntu if that helps) I am able to connect to the ftp server in FileZilla just fine, FileZilla did seem to automatically choose ftps. I am also able to ping this server.
Now this PHP Laravel (5.6) application is running on NGINX (had this for a while, everything else server-wise seems fine). As of now I am just trying to get this working locally, though there is a production server that it will have to be pushed onto (pretty much identical configuration though).
I started out trying to use the built in PHP function ftp_connect and ftp_ssl_connect - both using the same host and port number (990) as in FileZilla. I have been unable to get past this step - it returns false (so never even gets to my login logic).
$ftp = ftp_connect(env('FTP_HOST'),env('FTP_PORT')); // returns FALSE
$ftp = ftp_ssl_connect(env('FTP_HOST'),env('FTP_PORT')): // returns FALSE
After searching for a while I decided to try Laravel's filesystem to see if that would make it easier, these are my settings in config/filesystems.php:
'ftp' => [
'driver' => 'ftp',
'host' => env('FTP_HOST'),
'username' => env('FTP_USER'),
'password' => env('FTP_PASSWORD'),
'port' => env('FTP_PORT'),
'ssl' => true,
'timeout' => 60,
],
'sftp' => [
'driver' => 'sftp',
'host' => env('FTP_HOST'),
'username' => env('FTP_USER'),
'password' => env('FTP_PASSWORD'),
'port' => env('FTP_PORT'),
'timeout' => 60,
],
I figured I'd try both ftp and sftp here, I then tried the following:
Storage::disk('ftp')->put('test.csv', $file);
and
Storage::disk('sftp')->put('test.csv', $file);
The first just timed out, the second gave me the message: League\Flysystem\Sftp\ConnectionErrorException: Could not login with username: ###, host: ### in...
Any ideas of what this could be or next steps I could take towards troubleshooting would be greatly appreciated, I feel like I just don't know what to try to get a better understanding of what's wrong here. Thanks!
EDIT:
I realized that previously I had always used the quick connect feature in FileZilla for this. I looked into it further and was able to confirm that the encryption has to be implicit FTP over TLS - So I'm wondering if there is a setting for that I'm missing.
The port 990 is for implicit TLS/SSL, as you have eventually figured out.
The implicit TLS/SSL is not supported by the PHP built-in FTP implementation. Neither is implicit TLS/SSL supported by flysystem used by Laravel (which probably internally uses PHP built-in FTP anyway).
The implicit TLS/SSL was a temporary hack back in 90s to allow legacy FTP software to use encrypted connection without modification. It was never something that should have been used in long term, definitely not 30 years later! The implicit FTP never even became part of FTP standard. Only the explicit TLS/SSL was standardized by RFC 4217 in 2005. Since then, noone should be using implicit TLS/SSL ever.
Get your FTP server fixed to use the explicit TLS/SSL.
Take a look at the additional settings (https://flysystem.thephpleague.com/v2/docs/adapter/ftp/) you can add to the filesystem.php for your ftp settings. Match them with what you have on your FileZilla settings and see if it helps.
Laravel underneath uses the flysystem adapters to connect to different storage types and you can reference the settings from the above URL.
Since we started using mongoDB a while back, a large part of our PHP codebase looks like this:
$mongo = new Mongo();
$coll = $mongo->mydb->mycoll;
The default is to connect via TCP to localhost:27017 which has worked just fine for us for a few years now. Due to speed considerations, I would like to switch to using Unix domain sockets which are supported like this:
$client = new MongoClient("mongodb:///tmp/mongodb-27017.sock");
Is there a way to make this work without having to specify the socket file in the code? The docs list mongo.default_host and mongo.default_port which can be set in php.ini so you can write:
$client = new MongoClient();
but that seems to be possible only for TCP connections. Or can I use these parameters to specify a socket file? If so, how?
I am working on a Webservice and I'm using Predis as a redis library and I want the clients to be able to reuse the same TCP socket.
Currently , after running a load test on my service , I found that the number of socket in TIME_WAIT state increase fast on the server and at some point the connexion to Redis server gets refused.
According Redis documentation using PhpiredisStreamConnection with presistant option fixes the problem , but after adding this to my connect code , I m still facing the same issue. Any ideas?
Im using TCP connection as the redis instance are not on front servers.
<?php
include 'autoload.php';
$parameters = array(
'tcp://some.host01:6379?database=0&alias=master&persistent=1',
'tcp://some.host02:6379?database=0&alias=slave&persistent=1',
);
$options = array( 'replication' => true ,
'connections' => array('tcp' => 'Predis\Connection\PhpiredisStreamConnection','unix' => 'Predis\Connection\PhpiredisStreamConnection') );
$predis = new Predis\Client($parameters, $options);
?>
As per the documents Predis works for persistent connections when php process are configured as persistent process . Look at the following for more details :
https://github.com/joindin/joindin-web2/blob/master/vendor/predis-0.8/FAQ.md
http://php-fpm.org/
I am using redis as the driver for caching data. The database configuration of Laravel has the ability to define the Redis connection information.
'redis' => array(
'cluster' => true,
'default' => array(
'host' => '127.0.0.1',
'port' => 6379,
'database' => 0,
),
),
But if I wanted to have multiple connections defined and use a specific connection to use for the cache, how can I do this on Laravel 4. There is no connection configuration on cache.php where I can specify the redis connection name. It currently has a connection config that will be used if the cache driver is database.
EDIT
I just went through the Laravel code and when initializing the Redis Driver, it looks like Laravel is not looking into the connection. Is my understanding correct?
http://laravel.com/api/source-class-Illuminate.Cache.CacheManager.html#63-73
protected function createRedisDriver()
{
$redis = $this->app['redis'];
return $this->repository(new RedisStore($redis, $this->getPrefix()));
}
Laravel can handle multiple connections. See this question/answer on adding/using multiple database connections.
Once you define multiple connections for redis, you'll need to do some leg work to access those somewhere in your code. That might look something like this:
$redisCache = App::make('cache'); // Assumes "redis" set as your cache
$redisCache->setConnection('some-connection'); // Your redis cache connection
$redisCache->put($key, $value');
Edit
I'll add a little here to give you an idea of how to do this so you don't need the connection logic everywhere:
Most simply, you can bind an instance of your redis cache somewhere (perhaps a start.php or other app/start/*.php file) in your app:
App::singleton('rediscache', function($app){
$redisCache = $app['cache'];
$redisCache->setConnection('some-connection'); // Your redis cache connection
return $redisCache;
});
Then, in your code, you can do this to cache:
$cache = App::make('rediscache');
$cache->put($key, $value); // Or whatever you need to do
You can also create a Service Provider if you have your own application library of code. You can register 'rediscache' within there and then use it in the same way in your application.
Hope that helps as a start - there are other code architectures - using Dependency Injection and maybe a repository to help organize your code further.
Does the PHP client for MongoDB have support for SSL? Or is there a way to connect to MongoDB instance running in SSL?
I see in MongoDB docs that the client list does not specify for PHP (this link) but I am curious to see if anyone out there have tried or trying and to get an idea of the expected release etc.
Yes, the PHP driver supports this in the latest versions. In the connection string you should be able to add the "ssl" option like in the following two ways:
$m = new MongoClient( 'mongodb://localhost/?ssl=true' );
$m = new MongoClient( 'mongodb://localhost', array( 'ssl' => true ) );