自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(50)
  • 资源 (1)
  • 收藏
  • 关注

原创 RocketMQ与innoDB使用页缓存(PageCache)提升查询效率

什么是页缓存(PageCache)?页缓存(PageCache)是OS对文件的缓存,用于加速对文件的读写。一般来说,程序对文件进行顺序读写的速度几乎接近于内存的读写速度,主要原因就是由于OS使用PageCache机制对读写访问操作进行了性能优化,将一部分的内存用作PageCache。对于数据的写入,OS会先写入至Cache内,随后通过异步的方式由pdflush内核线程将Cache内的数据刷盘至物理磁盘上。对于数据的读取,如果一次读取文件时出现未命中PageCache的情况,OS从物理磁盘上访问读取文件的

2022-04-08 00:42:39 787

原创 nacos如何实现服务注册?

nacos为什么服务注册如此高效?源码分析nacos服务端使用内存方式存储服务实例时,底层采用异步+阻塞队列的方式实现服务的注册。当服务注册时,把服务实例数据写入阻塞队列,返回注册成功,然后异步的从阻塞队列获取实例数据进行注册,其实现流程如下:nacos服务端提供的restfull API接口为/v1/ns/instance,controller源码如下:@RestController@RequestMapping(UtilsAndCommons.NACOS_NAMING_CON

2022-01-22 11:29:07 4248

原创 CPU使用飙升,内存暴涨,jvm如何快速定位?

通常,操作线上服务器的权限是很受限制的。并且,线上服务器很少安装jvm可视化工具。甚至,连jdk的环境变量都不会配置(如果真的没有jdk环境变量,你是如何定位安装目录的?which java/where java)。如果,突然线上服务器告警,如何能过在几分钟之内快速定位问题呢?接下来使用jdk自带的jmap,jstack,jstat等命令,教你如何快速定位问题一、内存使用率升高内存的使用率在不断升高,垃圾回收以后也没有降低。这时,有可能出现了内存泄漏,即一个不会失效的对象的集合在不断的创建对象,

2021-12-26 22:12:30 1588

原创 为什么要写单元测试?基于junit如何写单元测试?

为什么要写单元测试一聊起测试用例,很多人第一反应就是,我们公司的测试会写单元测试用例的。我们研发到底要不要写单元测试用例呢?参考阿里巴巴开发手册,第8条规则(单元测试的基本目标:语句覆盖率达到 70%;核心模块的语句覆盖率和分支覆盖率都要达到 100%),大厂的要求就是必须喽。我个人感觉,写单元测试用例也是很有必要的,好处很多,例如:保证代码质量!!!无论初级,中级,高级开发工程的代码,功能是必要要保证是正确的;交付测试以后,bug锐减,联调飞快。 代码逻辑“文档化”!!!新人接手维护模块代码时,

2021-04-24 19:14:24 1318 6

原创 微服务系统保障选择Hystrix还是Sentinel?

Hystrix在spring cloud系统中,随着业务量的增加,默认选用Hystrix作为系统的熔断降级方案。由于,系统中使用security jwt方式做权限认证,服务之间feign使用RequestTemplate在header中传递token。开启Hystrix后,由于默认的隔离机制是线程池,在调用下游服务时,会重新创建线程,RequestContextHolder通过ThreadLocal无法获取token。如何让token传递到下游服务呢?可以使用hystrix信号量的机制进行服务的容错

2021-02-09 11:16:15 1042 2

原创 为什么要使用注册中心?是eureka还是nacos?

为什么要使用注册中心有使用过ip:port地址直接调用服务的开发经历么?该段痛苦的经历在此处省略500字......,该种方式的缺点:需要手动的维护所有的服务访问ip地址列表。 单个服务实现负载均衡需要自己搭建,例如基于容器化多实例部署单个服务,在实例之间做负载均衡。使用注册中心能够实现服务治理,服务动态扩容,以及服务调用的负载均衡,完整调用链路示例如下:服务提供者:向注册中心根据服务名称提供服务访问的ip:port以及其他信息。 注册中心:根据服务名称,存储对应的ip:port以及其

2021-01-14 20:48:31 11075 4

原创 微服务日志输出如何处理?

Api日志为了方便日志跟踪,api日志一般会要求显示请求路径,方法类型,执行时间,请求的入参,请求头,以及请求响应。如果是微服务之间的调用,需要设置全局的请求id用于标识整个链路请求。基于控制层的拦截器实现,定义LogFilter实现日志的输出。微服务之间请求的全局id通过header传递,使用HttpServlet的装饰类进行扩展header的设置。源码如下:public class LogFilter implements Filter { private static final

2020-12-11 17:31:09 2841

原创 如何使用validation类似于AOP切面的形式抽象参数的校验逻辑?

开发中,通常操作逻辑都是先进性数据校验,校验完毕以后才进行真正的逻辑处理。通常情况下,可以使用javax.validation校验注解,类似于AOP面向切面的实现数据的校验。在springboot中引入spring-boot-starter-web依赖,就会自动引入hibernate-validator。如图:内置注解使用javax.validation校验参数,一般在controller层,对方法参数进行校验。常用的注解包括:@NotNull,值不能为空,@Positive,数字为..

2020-11-30 17:03:28 3943 1

原创 什么是JWT?为什么选择JWT?如何在Spring Cloud Security集成使用?

什么是JWT?Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准,详情可以参考什么是 JWT -- JSON WEB TOKEN。其特点如下:具体时效性,包含失效时间。 具有安全性,基于密钥机制的签发和验证机制。为什么选择JWT?基于oauth2协议认证过程中,以密码类型认证方式为例,包括认证和授权两个步骤。分别如下:客户端通过客户端用户名和密码,密码授权方式,以及用户名和密码,向授权服务器认证,如果有效则返回token(访问令牌

2020-10-01 00:11:03 7319

原创 如何写好Java业务代码?这也是有很多规范的

在自己的工作过程中,对于代码的规范总结出以下几点,如果有不足的希望大家指出。枚举类的使用在业务中特别是状态的值,在对外发布api的vo对象中,加上状态枚举值的注释,可以让调用方一目了然。示例: public class ProductVo implements Serializable { /** * 审核状态 * {@link ProductStatus} */ @ApiModelProperty("状态") private Integer s

2020-09-04 12:49:46 6669 2

原创 如何使用Nacos实现数据库连接的自动切换?

为什么使用nacos?Nacos作为参数配置中心,可以使服务在不重启的情况下动态修改配置参数。官网的描述更加详细点,如下:动态配置服务动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。Nacos 提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。Nacos 还提供

2020-08-21 18:39:54 11989

原创 Dubbo服务导出如何实现的?我们从中能够学习到什么?

Dubbo通过注解或者xml形式标识Dubbo服务,在Spring 容器发布刷新事件,会立即执行服务导出逻辑,示例如下:import com.alibaba.dubbo.config.annotation.Service;import org.springframework.beans.factory.annotation.Autowired;import java.util.List;import java.util.stream.Collectors;/** * 价格服务 **/

2020-06-20 14:17:10 1035

原创 Dubbo SPI是什么?Dubbo SPI如何实现?我们从中能够学习到什么?

Dubbo SPI是什么Dubbo SPI(Service Provider Interface),用于根据名称获取Interface接口的实现类,根据条件激活Interface接口的实现类集合,即一组实现类。并且是根据JAVA SPI扩展而来,具有如下特性:按需要加载Interface接口的实现类,JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实,现初始化很耗时,但如果没用上也加载,会很浪费资源。 增加了对扩展点 IoC 和 AOP 的支持,一个扩展点可以直接 setter 注

2020-06-18 23:28:43 1664

原创 如何使用MyBatis的plugin插件实现多租户的数据过滤?

在中台服务,或者saas服务中,都会因为存在不同的租户的入驻,需要保证不同租户的数据隔离。通常的解决方案,是将数据存在同一个数据库,然后,使用租户的标识为所有的业务数据做数据隔离。如果采用此种方案,如何快速的在数据中间层做数据隔离呢?我使用了mybatis的plugin插件机制,对query操作进行拦截实现数据的过滤。大致的流程如下:...

2020-06-11 20:38:41 10734 1

原创 代理(Proxy)是什么?为什么要使用代理模式?Spring与Dubbo如何运用代理模式的?

代理是什么代理模式,就是为其他的对象提供一种代理,以控制对这个对象的访问。Proxy代理对象与被代理对象对于调用方来说,完全一致,并且Proxy代理对调用方隐藏了被代理对象的实现细节。流程如下:为什么要使用代理模式没错,代理模式就是这么简单,可以这么理解,Proxy代理对象向调用方统一了对被代理对象的所有方法。有时,在调用被代理对象的正在执行的方法前,可能需要增加参数的校验逻辑,或者打印日志的逻辑;在执行完方法后,可能需要统计执行的时间,触发结束的事件等等逻辑。此时,如果在Proxy代理对象

2020-06-04 23:36:41 6455

原创 为什么要使用线程池?dubbo是如何扩展的?

为什么要使用线程池多线程能够提高系统的并发性,充分利用服务的资源。但是,如果无限制的创建线程,反而会拖垮服务器的性能。一是创建线程是一个耗资源的操作,二是过多的线程会加剧线程上下文切换,竞争CPU。所以,会对线程使用池化的方案,重复的利用已经创建的线程。在Java中使用ThreadPoolExecutor定义线程池,其部分的源码如下: /** * ThreadPoolExecutor 初始化方法 */ // ThreadPoolExecutor.class

2020-06-03 23:23:51 3669

原创 Netty如何实现常见的两种线程模式?dubbo基于Netty发布服务时如何选择线程模式?

在基于Netty的网络编程中,Channel定义了网络通信的两端,例如,客户端SocketChannel与服务端SeverSocketChannel。EventLoop定义了通信Channel触发的各类事件的监听,例如,客户端连接请求。EventLoopGroup定义了一组EventLoop。通常,EventLoop与一个Thread绑定,EventLoop与Channel绑定后,两者关联关系就不会改变。以服务端接收监听客户端的为例,执行流程如下:Netty实现的线程模式可以参考为什么要使用NIO.

2020-05-31 22:44:36 3558

原创 责任链如何设计?Tomcat和Netty分别是如何实现过滤器链和事件链?

在业务开发中,对于同一类逻辑处理,一般都是都是归类为一组集合,类似于一条业务链来处理,流程如下:举个例子,在下单过程中,会对生成订单进行很多条件判断。通常,会定义一个校验接口Validator定义生成订单的条件判断业务的抽象;在下单过程因为有很多不同的条件判断,所以,就会在下单的服务中,定义类似于一组的校验业务,例如,定义集合List<Validator> validators。如果,在链式业务处理过程中,对于不同的订单会有校验逻辑需要满足条件才能判断,这时如何进行过滤呢?如果在不同

2020-05-22 20:03:34 3621

原创 为什么要使用NIO?Tomcat是如何解决服务器端高并发的请求

为什么要使用NIO在Java中使用Socket(套接字)实现了基于TCP/IP协议的网络编程。以HTTP协议为例,在HTTP服务器端的开发中,如果不使用NIO该如何实现呢?单个线程定义客户端连接使用ServerSocket绑定某个端口号,监听客户端的请求,如果有客户端向服务端发送请求,就会建立TCP连接,生成Socket客户端,与服务器基于i/o流实现信息交互。示例代码如下:public static void main(String[] args) { ServerSoc

2020-05-19 23:06:00 4286

原创 商品库存的扣除过程中如何防止超卖?

在商品购买的过程中,库存的抵扣过程,一般操作如下:select根据商品id查询商品的库存。 根据下单的数量,计算库存是否足够,如果存库不足则抛出库存不足的异常,如果库存足够,则减去扣除的库存得到最新的库存剩余值。 set设置最新的库存剩余值。上述过程的伪代码如下:// 根据商品id获取商品剩余库存select stock_remaing from stock_table wher...

2020-04-16 23:16:02 11836 3

原创 为什么会数据不一致?常见分布式实现方案有哪些?

数据库事务的ACID特性数据库事务特性包括原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily)。以下单为例,在单体的电商系统中,调用下单服务,整个服务操作在同一事务中完成。下单成功以后,扣减库存,生成订单操作会同时生效,数据都会写入库存数据库,订单数据库。流程如下:在分布式系统中,如果只是将下单服务...

2020-04-14 20:35:02 6412

原创 什么是CAP?适用的场景有哪些?

概述在分布式系统中,围绕着CAP理论,主要关注点就是复制,一致性,容错性。复制为了保证系统的高可用和高可靠性,通过复制的方式,让服务实例运行多个副本,数据在系统中也存储多个发副本。以服务实例多副本为例,当一个服务发生异常时,客户端就直接调用其他正常的副本。如下:服务A有两个副本,分别为副本1和副本2。当客户端调用服务A时,如果服务A发生异常无法调用,此时,客户端调用副本1或者...

2020-04-11 22:30:21 9928

原创 消息中间件之常见使用场景

概述消息中间件例如,Kafka,RocketMQ和RabbitMQ等等,是业务开发中不可或者的组件。通常消息中间件包括3个角色组成,如下:生成者(Producer),生产消息。 消息代理(message broker),存储生产者产生的消息。 消费者(Consumer),从消息代理获取并消费消息。大致流程图如下:常见场景通常消息的使用场景有如下几类:应用解耦 流量...

2020-04-10 23:12:50 3908

原创 什么是双亲委派?Tomcat是如何扩展ClassLoader的?

在JVM中,首次使用某个类时,JVM会把.class文件的二进制子节流加载到内存的方法区,创建对应的Class对象。虚拟机设计团队把类加载阶段中的通过一个类的全限定名来获取描述此类的二进制字节流这个动作交由ClassLoader类来实现。而判断一个Class对象是否相等,需要根据Class对象和ClassLoader类加载器同时判断,在创建Class对象时,会设置对应的ClassLoader类加载...

2020-04-07 23:38:55 6690

原创 为什么JVM老年代要使用CMS垃圾回收器?

CMS(concurrent mark sweep)并发标记清理收集器以获取最短回收停顿时间为目标的收集器,特别适用于互联网网站或者B/S系统的服务端上,这类重视服务响应速度的,给用户良好的体验的情况。运行流程CMS收集器使用多线程技术,基于标记-清理算法,实现了老年代并发地标记和清理。其运行地步骤如下:初始标记(CMS initial mark),停止所有用户线程(stop the ...

2020-04-06 00:15:29 6680 1

原创 秒杀场景之双11双12商品促销实现方案

场景介绍在双十一和双十二进行酒类产品销售时,场景类似于秒杀业务场景,在短时间内,有大量用户进行抢购。用户根据自己拥有的购酒资格进行抢购,在此轮抢购中,实时查看剩余可以购酒的瓶数,抢购成功,则完成后续的支付操作。实现方案多级缓存用户频繁的操作就是频繁的查询购买的商品。对于促销商品和价格的信息,提前预制到redis缓存,失效时间通常设置为24小时。对于用户信息缓存,使用本地缓存,通常设置失效...

2020-03-31 22:32:21 5784

原创 深入理解volatile和使用场景

volatile特性和实现原理volatile 实现了共享变量的线程安全,在多线程操作单个volatile变量时,保证了线程间的可见性。根据happens-before规则,对一个volatile共享变量的写操作,总是happens-before对该volatile共享变量的读操作。当线程对volatile共享变量进行写操作时JMM会把线程对volatile共享变量写操作后,修改的值刷新...

2020-03-25 21:55:11 605

原创 出行行业计价模块的设计模式实践

业务场景介绍在价格的计算中,通常的流程如下:根据一组价格配置,计算订单基础的价格。 根据用户拥有的优惠对象,例如优惠券,积分,会员级别等,计算出优惠以后的价格。如上,价格计算的流程就算完了,是的,流程就是这么简单,简单到流程图都省略了,你会怎样去设计这段流程的代码呢?根据设计模式中开闭原则,单一原则,依赖倒转原则。在该模块中,总共涉及到装饰模式,策略模式,单例模式,工厂类,责任链模式,...

2020-03-23 00:56:31 3896

原创 深入理解Spring Cloud Zuul网关和使用场景

网关的好处在单体应用程序架构下,客户端( Web 或移动端)通过向服务端发起一次网络调用来获取数据 。 负载均衡器将请求路由给 N 个相同的应用程序实例中的一个 。 然后应用程序会查询各种数据库表处理业务逻辑,并将响应返回给客户端。 微服务架构下,单体应用被切割成多个微服务,如果将所有的微服务直接对外暴露,势必会出现安全方面的各种问题。客户端可以直接向每个微服务发送请求,其问题主要包括:...

2020-03-19 07:44:07 5088

原创 深入理解OAuth2协议和使用场景

OAuth2协议概述生活中,当我们使用滴滴出行或者美团app进行登录时,如果选择微信授权登录,则可以使用微信的头像,昵称,地区和性别信息登录,如图:在滴滴出行和美团app的系统中,是没有存储微信的用户信息,但是授权过后就可以使用到微信的部分权限。这操作过程就是基于OAuth2协议实现的。OAuth2是当前授权的行业标准,OAuth2中有4种角色Resource Owner,资源所有...

2020-03-15 22:47:35 4218

原创 玩转Spring Cloud Security OAuth2资源授权动态权限扩展

Spring Cloud Security OAuth2授权信息,属于一次加载,然后缓存到资源服务。如果在运行时,有两种方式动态获取权限信息。实现AccessDecisionVoter接口,自定义授权逻辑和实现FilterInvocationSecurityMetadataSource自定义url路径需要授权的信息。方式一:实现AccessDecisionVoter接口示例中,根据user...

2020-03-08 13:49:12 8304

原创 深入理解Spring Cloud Security OAuth2资源授权

在Spring Cloud Security 中,认证和授权都是通过Servlet Filter拦截,处理完成后然后再转发到对应的Servlet请求。认证成功后,会被FilterSecurityInterceptor Filter拦截,进入授权部分,如果应用中配置了对权限的控制,这就将生成对应的过滤器对其进行权限控制。AccessDecisionManager接口,定义了授权处理,源码如下:...

2020-03-08 12:57:12 2702

原创 玩转Spring Cloud Security OAuth2身份认证扩展——电话号码+验证码认证

在程序的认证过程中,除了常规的用户名和密码方式(可以参考手把手教你玩转Spring Cloud Security OAuth2认证),也经常会出现电话号码+密码的方式;电话号码+验证码的方式;或者第三方软件的方式。以下,以电话号码+验证码的方式讲述OAuth2认证方式的扩展。在OAuth2认证开始认证时,会提前Authentication认证信息,然后交由AuthenticationManag...

2020-03-07 00:13:12 5157 2

原创 深入理解Spring Cloud Security OAuth2身份认证

OAuth2协议生活中,当我们使用滴滴出行或者美团app进行登录时,如果选择微信授权登录,则可以使用微信的头像,昵称,地区和性别信息登录,如图:在滴滴出行和美团app的系统中,是没有存储微信的用户信息,但是授权过后就可以使用到微信的部分权限。这就是使用OAuth2协议实现的。它为第三方应用提供对HTTP服务的有限访问,即可以是资源拥有者通过授权运行第三方应用获取HTTP服务,也可以是第...

2020-03-06 23:43:49 4593

原创 深入理解synchronized锁和使用场景

synchronized使用场景在java中,提供了synchronized实现共享对象的并发访问。当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。通常有三种使用方式,如下:对于普通同步方法,锁是当前实例对象。 对于静态同步方法,锁是当前类的Class对象。 对于同步方法块,锁是Synchonized括号里配置的对象。线程安全类在java8源码中,提供...

2020-02-28 17:42:14 1093

原创 使用java命令jps和jstack快速定位线程状态

线程状态定义在线上项目中,当程序处于长时间停顿的时候,可以使用java提供的jstack命令跟踪正在执行方法的堆栈情况。jstack能够生成虚拟机当前时刻的线程堆栈情况。主要,监控线程的状态,判断出线程停顿的原因。例如,死锁,死循环,多个线程等待等等。线程的状态包括NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED,其源码如下:pu...

2020-02-27 14:00:34 1501 1

原创 聚集索引和辅助聚集索引-教会你正确的使用mysql索引

索引原理当从数据库中读取数据时,由于磁盘的访问代价很高,一般的磁盘每秒做100次IO操作,2-3次的IO操作意味着查询时需要0.02~0.03秒。而数据库中的数据,都是基于B+树(B+树可以参考B+树-分分钟钟被安排地明明白白)的数据结构存储数据。在mysql中,数据结构分为聚集索引(clustered index)和辅助聚集索引(secondary index)。索引的特性如下:聚集索引...

2020-02-24 21:28:22 548

原创 HashMap-Java8源码教会你正确的使用方式

HashMap在Java中,基于散列表(hash table)实现的。其特性如下:HashMap使用分离链接法存储节点hash冲突的元素,使用基于单链表Node和基于红黑树的TreeNode存两种方式储冲突的对象。 填充因子默认为0.75,当添加元素使填充因子大于loadFactor设置的值,则就HashMap就需要扩容,并且再散列。 被加载的对象在java中必须实现int hashCod...

2020-02-23 20:11:22 280

原创 TreeMap-Java8源码教会你正确的使用方式

TreeMap在java中,是基于红黑树的原理实现的(红黑树的原理请参考红黑树(red black tree)-分分钟钟被安排地明明白白),其原理是一棵有条件的平衡二叉查询树。节点定义包含了左右儿子节点,父节点,颜色标识。源码如下: /** * 红黑树节点 */ static final class Entry<K,V> implements M...

2020-02-23 14:32:14 176

原创 List列表集合,Iterator迭代器-Java8源码教会你正确的使用方式

ArrayList集合在java中,基于数组实现,get(i)查询操作时间复杂度为O(1)。add新增和remove操作存在潜在的昂贵时间花销。因为,对数组中某个位置的元素(非尾元素)进行add和remove操作,该元素后的所有元素会进行整体移动复制操作。当add操作时,添加元素的个数大于集合容量,arraylist会进行扩容处理,重新创建原始容量2倍大小的数组,然后进行数据复制操作。ar...

2020-02-18 23:10:36 388

paoding rose 框架实例

环境配置为maven3.1.1,tomcat6.0.41,jdk1.7,myeclipse10,mysql数据库。使用paoding rose框架,spring3,mybatis3;在dao层简单进行BaseDao设计;用VM实现页面显示。 在controller层实现了单条user数据的显示。

2015-08-27

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除