ssh端口转发
Redis服务器在官网公开了使用的协议(RESP),此时任何一个第三方都可以通过上述协议,来实现出一个和redis服务器通信的客户端程序.
现在,已经有很多库可以让我们直接调用,就不必关注redis协议的细节了.
在java的生态中,封装了RESP协议,实现的redis客户端有很多,我们此处使用的是jedis,jedis中提供的api和redis命令是高度一致的.
jedis也可以通过maven仓库来引入我们的maven项目.
<!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>4.4.2</version> </dependency>
引入好了之后,下一个问题就是如何使我们的windows电脑上的redis客户端能够访问到linux云服务器上的redis服务器.
此时只知道云服务器的外网IP是不够的,我们知道我们的redis服务器是绑定在云服务器的6379端口上的,而此端口默认是被云服务器的防火墙保护起来的.此时这个端口是不能被外界访问的,防火墙一旦保护,不仅黑客访问不了,我们自己跨主机通过外网也是访问不了.
那么,如果在云服务器后台,将6379端口对应的防火墙打开,就可以访问了.
但是我们不可以这么做,非常危险!!!Redis的端口一旦公开到外网上,就特别容易被入侵.
虽然我们的tomcat的8080端口也开放了,但是tomcat的安全系数是比较高的,而redis的安全系数比较低,更加容易被入侵.
那么现在,我们不能开放redis的端口,同时还要能够让自己通过外网访问redis服务器,如何做?
配置ssh端口转发,把云服务器的redis端口,映射到本地主机的端口.
ssh也是一个协议,也是一个运行程序,默认是在云服务器的22端口,ssh的功能非常强大,其中很重要的功能就是能够支持端口的转发.相当于通过ssh的22端口来传递其他端口的数据.
我们要访问linux云服务器上的6379端口,此时就可以通过ssh进行端口的映射,把服务器的6379映射到本地的端口比如8888端口.
现在我们需要通过windows主机,访问云服务器的6379端口,我们就可以构造一个特殊的ssh数据包,就要把访问redis的请求,放到ssh数据报里.
这个数据就会通过22端口发送给服务器,服务器的ssh服务器程序就会解析出上述的数据包,然后把数据交给6379端口的程序.
一个linux主机上,存在的服务器有很多,ssh也可能需要给多个端口来传递数据,这个时候为了区分不同的端口,往往会把服务器的端口在本地用另外一个端口来进行表示.
只需要简单的配置,后续就把云服务器的端口当成一个本地的端口使用即可.
ssh端口转发也叫ssh端口映射也叫做ssh隧道.
当ssh连接上了之后,端口转发才生效,把ssh连接断开了,端口转发就失效了.连接完整之后,使用netstat命令查看本地的8888端口是否启动了.
当配置了端口转发后,一定要断开之前的连接,重新连接才生效.
此时我们的java代码中,通过127.0.0.1:8888就能操作到云服务器的redis了,同时外面的客户端,是无法直接访问云服务器的6379的.
这里我们的程序能跑通,除了配置ssh端口转发之后,还有一个要点,就是我们在最开始安装redis服务器的时候,在配置文件里修改了ip为0.0.0.0以及关闭了保护模式.
默认绑定的ip为127.0.0.1,此时只能本机的客户端访问本机的redis服务器,不能跨主机访问.
默认的保护模式是开启,跨主机也是不能访问的.
这样就又起到了保护作用,也能够让我们访问!!!
jedis下的命令
建立一个redis连接池,从池子中取出一个redis连接.
连接用完之后要记得关闭(close),此处的关闭,不一定是真的关闭tcp连接,而是将连接放回到了池子里.
通过jedis对象就能执行各种各样的方法(命令),jedis对象的方法命名是和redis中的命令高度一致的,所以我们掌握了redis中的命令,在这里使用起来也是非常容易的.
演示一些命令
public static void main(String[] args) { JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888"); try(Jedis jedis = jedisPool.getResource()){ //redis的各种命令就都对应到jedis对象的各种方法 //test1(jedis); //test2(jedis); test3(jedis); } } public static void test1(Jedis jedis){ System.out.println("get和set"); //先清空数据库,避免上一组测试的残留数据影响到下一组测试的结果 jedis.flushAll(); jedis.set("key1","111"); jedis.set("key2","222"); //表示一个set命令的选项部分 SetParams setParams = new SetParams(); setParams.ex(10); setParams.nx();//不存在才创建 jedis.set("key3","333",setParams); String value = jedis.get("key3"); System.out.println("value: " + value); //mset jedis.mset("key1","v1","key2","v2","key3","v3"); //mget List<String> vals = jedis.mget("key1","key2","key3"); System.out.println(vals); //exists Boolean result = jedis.exists("key4"); System.out.println("result: "+result); //del,返回的是删除的元素个数 Long dels = jedis.del("key3","key2"); System.out.println("删除的元素个数:"+dels); } public static void test2(Jedis jedis){ System.out.println("keys *"); jedis.flushAll(); jedis.mset("key1","v1","key2","v2","key3","v3","key4","v4"); Set<String> keys = jedis.keys("*"); System.out.println(keys); System.out.println("expire和ttl"); jedis.expire("key1",10); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } Long time = jedis.ttl("key1"); System.out.println(time); } public static void test3(Jedis jedis){ System.out.println("type"); jedis.flushAll(); jedis.set("k1","1111"); String type = jedis.type("k1"); System.out.println("type:"+type); jedis.hset("k2","f1","v1"); type = jedis.type("k2"); System.out.println("type:"+type); jedis.lpush("k3","11","22"); type = jedis.type("k3"); System.out.println("type:"+type); jedis.sadd("k4","member1","member2"); type = jedis.type("k4"); System.out.println("type:"+type); jedis.zadd("k5",10,"m1"); type = jedis.type("k5"); System.out.println("type:"+type); }public static void test4(Jedis jedis){ System.out.println("setrange和getrange"); jedis.flushAll(); jedis.set("k1","abcdefghi"); String result = jedis.getrange("k1",0,5); System.out.println("result:"+result); jedis.setrange("k1",2,"ttt"); result = jedis.getrange("k1",0,-1); System.out.println("result:"+result); System.out.println("append"); jedis.set("k2","aaaa"); jedis.append("k2","bbb"); result = jedis.get("k2"); System.out.println("result:"+result); System.out.println("计数相关"); jedis.set("k3","100"); Long count = jedis.incr("k3"); System.out.println("count:"+count); count = jedis.decr("k3"); System.out.println("count:"+count); count = jedis.incrBy("k3",50); System.out.println("count:"+count); count = jedis.decrBy("k3",100); System.out.println("count:"+count); }