Recent Posts

Posted in java 技术博客

分布式锁的几种实现方式

目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance),最多只能同时满足两项。”所以,很多系统在设计之初就要对这三者做出取舍。在互联网领域的绝大多数的场景中,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证“最终一致性”,只要这个最终时间是在用户可以接受的范围内即可。 在很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务、分布式锁等。有的时候,我们需要保证一个方法在同一时间内只能被同一个线程执行。在单机环境中,Java中其实提供了很多并发处理相关的API,但是这些API在分布式场景中就无能为力了。也就是说单纯的Java Api并不能提供分布式锁的能力。所以针对分布式锁的实现目前有多种方案。 针对分布式锁的实现,目前比较常用的有以下几种方案: 基于数据库实现分布式锁 基于缓存(redis,memcached,tair)实现分布式锁 基于Zookeeper实现分布式锁 在分析这几种实现方案之前我们先来想一下,我们需要的分布式锁应该是怎么样的?(这里以方法锁为例,资源锁同理) 可以保证在分布式部署的应用集群中,同一个方法在同一时间只能被一台机器上的一个线程执行。这把锁要是一把可重入锁(避免死锁)这把锁最好是一把阻塞锁(根据业务需求考虑要不要这条)有高可用的获取锁和释放锁功能获取锁和释放锁的性能要好 基于数据库实现分布式锁 基于数据库表 要实现分布式锁,最简单的方式可能就是直接创建一张锁表,然后通过操作该表中的数据来实现了。 当我们要锁住某个方法或资源时,我们就在该表中增加一条记录,想要释放锁的时候就删除这条记录。 创建这样一张数据库表: 当我们想要锁住某个方法时,执行以下SQL: 因为我们对method_name做了唯一性约束,这里如果有多个请求同时提交到数据库的话,数据库会保证只有一个操作可以成功,那么我们就可以认为操作成功的那个线程获得了该方法的锁,可以执行方法体内容。 当方法执行完毕之后,想要释放锁的话,需要执行以下Sql: 上面这种简单的实现有以下几个问题: 1、这把锁强依赖数据库的可用性,数据库是一…

Continue Reading...
Posted in java

Java基础常见笔试题总结

1.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。 2.“static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?“static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。 3.是否可以在static环境中访问非static变量?static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。 4.Java支持的数据类型有哪些?什么是自动拆装箱?Java语言支持的8中基本数据类型是:• byte• short• int• long• float• double• boolean• char自动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把int转化成Integer,double转化成double,等等。反之就是自动拆箱。 5.Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载O verloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被”屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 6.Java支持多继承么?不支持,Java不支持多继承。每个类都只能继承一个类,但是可以…

Continue Reading...
Posted in 技术博客

原生HTML页面添加标签支持

添加js代码

Continue Reading...
Posted in 技术博客

Redis学习

 Redis存储key-value类型的数据。接下来介绍Redis的内存模型   两个重要参数: used_memory和used_memory_rss used_memory:redis分配器分配的内存 used_memory_rss:操作系统下redis进程分配的内存  前者是从redis角度上获得的量,后者是从操作系统角度上得到的量。二者有所不同,一方面是redis进程和内存碎片会占用内存,使得后者比前者大。另一方面,由于虚拟内存的存在,使得前者比后者大。   进程所占用的内存与内存碎片和Redis数据量相比,会小的多。因此,userd_memeory和used_memory_rss的比值就成了redis内存碎片率的参数。这个参数就是- mem_fragmentation_ratio mem_fragmentation_ration的定义:used_memory_rss/used_memeory   一般来所,mem_fragmentation的比值大于1,该值越大,内存碎片比例越大。<1说明redis使用了虚拟内存,由于虚拟内存的媒介是磁盘,比内存速率要慢很多,当这种情况出现时,应该及时排查,如果内存不足应该及时处理,比如增加Redis节点,增加redis服务器的内存,优化应用等。 mem_allocator:redis使用的内存分配器,一般来说,有:libc,jemalloc,tcmalloc。默认是jemalloc redis的内存划分,主要分一下几个部分 1.数据 存储的主要是数据,这部分内存统计在used_memory中 2.进程本省运行所需要的内存 如代码、常量池等等,这部分内存与redis数据内存相比可以忽略不计,也不会被统计在used_memory中,另外,redis进程下的子进程也会占用内存,不属于redis进程,也不会被统计到used_memory和used_memory_rss中 3.缓冲内存 包括客户端缓冲区,复制积压缓冲区,AOF缓冲区,这部分内存由jemalloc分配,因此会被计入used_memory中 4.内存碎片 Redis在分配,回收物理内存过程中产生的。比如在redis产生的数据在物理内存中没有有效释放,但redis有没有对它有效利用,这就形成了内存碎片,内存碎片不会被统计到used_memory中。 Redis服务…

Continue Reading...
Posted in java

rocketMq

RocketMQ 是出自 A 公司的开源产品,用 Java 语言实现,在设计时参考了 Kafka,并做出了自己的一些改进,消息可靠性上比 Kafka 更好,目前,RocketMQ 的文档仍然不够丰富 1 2,社区仍然无法与 Kafka 比肩,但 A 公司已经推出了基于 RocketMQ 的云产品 3,相信未来 RocketMQ 也会有不错的发展。本文采用 RocketMQ 3.2.6 进行实验,由于 RocketMQ 与 Kafka 很相似,本文很多地方对两者做出了比较。 基本概念 RocketMQ 由于借鉴了 Kafka 的设计,包括组件的命名也很多与 Kafka 相似,下面摘抄一段《RocketMQ 原理简介》中的介绍,可以与 Kafka 的命名比对一下, Producer,消息生产者,负责产生消息,一般由业务系统负责产生消息。 Consumer,消息消费者,负责消费消息,一般是后台系统负责异步消费。 Push Consumer,Consumer 的一种,应用通常向 Consumer 对象注册一个 Listener 接口,一旦收到消息,Consumer 对象立 刻回调 Listener 接口方法。 Pull Consumer,Consumer 的一种,应用通常主动调用 Consumer 的拉消息方法从 Broker 拉消息,主动权由应用控制。 Producer Group,一类 Producer 的集合名称,这类 Producer 通常发送一类消息,且发送逻辑一致。 Consumer Group,一类 Consumer 的集合名称,这类 Consumer 通常消费一类消息,且消费逻辑一致。 Broker,消息中转角色,负责存储消息,转发消息,一般也称为 Server。在 JMS 规范中称为 Provider。 《RocketMQ 原理简介》中还介绍了一些其他的概念,例如,广播消费和集群消费,广播消费是 Consumer Group 中对于同一条消息每个 Consumer 都消费,集群消费是 Consumer Group 中对于同一条消息只有一个 Consumer 消费。Kafka 采用的是集群消费,不支持广播消费(好吧,是我没有找到)。再例如,普通顺序消息和严格顺序消息,普通顺序消息在 Broker 重启情况下不会保证消息顺序性;严格顺序消息即使在异常情况下也会…

Continue Reading...
Posted in linux nginx

ubuntu安装wikimedia使用nginx/二级域名

下载mediawiki的安装包 wget https://releases.wikimedia.org/mediawiki/1.31/mediawiki-1.31.0.tar.gz 解压 tar -zxvf mediawiki-1.31.0.tar.gz 复制到/var/wiki/html目录 cp -r /mediawiki-1.31.0/. /var/wiki/html 配置nginx server { listen 80; server_name wiki.yourdomain.com; root /var/wiki/html; index index.php index.html index.htm; location / { try_files $uri/ /index.php?$args; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/run/php/php7.0-fpm.sock; fastcgi_index index.php; include fastcgi.conf; } location ~* \.(js|css|png|jpg|jpeg|gif|ico|eot|otf|ttf|woff)$ { add_header Access-Control-Allow-Origin *; add_header Cache-Control “public, max-age=31536000, immutable”; access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } location ~ /\. { deny all; access_log off; log_not_found off; } } /usr/loca/nginx/sbin/nginx -s reload 配置域名解析 访问 wiki.yourdomain.com 搞定

Continue Reading...
Posted in linux nginx

Ubuntu下Nginx开启SSL报错nginx: [emerg] unknown directive “ssl”

去nginx解压目录下执行 ./configure –with-http_ssl_module 报错,没有OpenSSL库 安装openssl apt-get install openssl apt-get install libssl-dev ./configure –with-http_ssl_module 执行 make make 将原来 nginx 备份 cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak 将新的 nginx 覆盖旧安装目录 cp objs/nginx /usr/local/nginx/sbin/nginx 再试一下 /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf 成功 参考资料:https://blog.csdn.net/weiyangdong/article/details/80008543

Continue Reading...
Posted in nginx

搭建ngrok实现内网穿透(使用nginx代理)

背景介绍:之前使用的ngrok服务挂了 搭建环境 Ubuntu Server 16.04 LTS 64位 安装git sudo apt-get install build-essential golang mercurial git 获取源码 git clone https://github.com/tutumcloud/ngrok.git ngrok 生成替换证书 cd ngrok NGROK_DOMAIN=”ngrok.itcuc.cc” openssl genrsa -out base.key 2048 openssl req -new -x509 -nodes -key base.key -days 10000 -subj “/CN=$NGROK_DOMAIN” -out base.pem openssl genrsa -out server.key 2048 openssl req -new -key server.key -subj “/CN=$NGROK_DOMAIN” -out server.csr openssl x509 -req -in server.csr -CA base.pem -CAkey base.key -CAcreateserial -days 10000 -out server.crt cp base.pem assets/client/tls/ngrokroot.crt 编译源码(生成客户端) sudo make release-server release-client 生成windows下的客户端 GOOS=windows GOARCH=amd64 make release-client 启动服务 sudo ./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain=”ngrok.itcuc.cc” -httpAddr=”:8081″ -httpsAddr=”:8082″ 配置域名解析 配置nginx代理 在nginx.conf中加入 server { listen 80; server_name *.ngrok.itcuc.cc ngrok.itcuc.cc; location / { proxy_set_header X-Real-IP $remote_addr…

Continue Reading...
Posted in springboot

spring-boot+mybatis+restful api+jwt登陆(2)

前文回顾spring-boot+mybatis+restful api+jwt登陆(1) 用spring-boot开发RESTful API非常的方便,在生产环境中,对发布的API增加授权保护是非常必要的。现在我们来看如何利用JWT技术为API增加授权保护,保证只有获得授权的用户才能够访问API。 ####1. 引入security和jwt依赖 前文已经引入了这两个包,这里再看一下这两个是如何引入的 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency> ####2. 增加注册功能 利用前文引入的mybatis自动生成代码的插件,生成model和mapper – User类,省略setter和getter方法 public class User { private String id; private String username; private String password; private String email; private String mobile; private String loginIp; private Date loginTime; private Byte isAviliable; private Integer type; private String avatar; } UserMapper public interface UserMapper { int deleteByPrimaryKey(String id); int insert(User record); int insertSelective(User record…

Continue Reading...
Posted in springboot

spring-boot+mybatis+restful api+jwt登陆(1)

1. pom.xml 包含了mybatis代码生成插件,c3p0连接池 <?xml version=”1.0″ encoding=”UTF-8″?> <project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”> <modelVersion>4.0.0</modelVersion> <groupId>com.itcuc</groupId> <artifactId>qaserver</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>qaserver</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> <relativePath/> <!– lookup parent from repository –> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outp…

Continue Reading...