SpringCloud系列-负载均衡
负载均衡负载均衡,是一种计算机的技术,用来在多个计算机,网络连接,CPU,磁盘驱动器或其他资源中分配负载,已达到资源利用率最高,吞吐率最大换,最小化响应时间,同时避免过载的问题。(wiki)
在我们常见的微服务的架构当中,注册中心负责服务的注册和发现,但是,它也只能作为服务的提供者,如果我们需要获取某个服务,可以通过注册中心提供的Api获取对应的服务,但是,一般都会返回一个服务列表,所以,我们需要从中选取其中一个,作为我们需要的实例返回。这就需要一个新的算法来解决选取这一过程–负载均衡。
常见的负载均衡算法:
随机算法:随机选取
轮训算法:一个一个轮询选取
最少连接数算法:选取连接数最小的是咧
一致性哈希算法:
权重随机算法:不同实例权重不同,看随机数落在那个权重范围内,则选取哪个
负载均衡是一种通用的特性,所有的RPC框架都会有这个概念的实现。Apache Dubbo使用的是Load Balancer组件来实现的,Spring Cloud使用的是Nexflix Ribbon,并在将来用SpringCloud LoadBalancer(SCL)来作为替代品。SCL虽然已经问世,但是 ...
Java并发工具包 CyclicBarrier
CyclicBarrier循环屏障,也是一个同步助手工具,它允许多个线程在执行完某些操作之后,到达某个障点(barrier point)进行阻塞,当分片数为0时,再继续进行之后的操作。和CountDownLatch在功能上并无太大差别。
CyclicBarrier vs CountDownLatch与CountDownLatch相比,也是他们在功能上似乎是一致的,但是,在实现上,和应用上,有些地方是有很大不同。比如:
CountDownLatch设置完count数之后,只能使用一次,也就说,count为0之后,这个代码就到头了,不能再次使用
CyclicBarrier也需要设置初始值,被称”分片”,功能上差不多,也是计数器,但是,如果这个count到0之后,代码会将其进行重置,无需重新初始化一个,可以重复使用。这种特性被称为循环特性
CyclicBarrier分片数不能为0,CountDownLatch可以为0
CyclicBarrier是有Lock和Condition实现的。CountDownLatch是由AQS
多出的这个特性,就让CyclicBarrier有了很大的发挥空间, ...
Java并发工具包 CountDownLatch
CountDownLatch倒计数门阀。一般用在多任务的情景中。一个主任务,多个副任务,而且需要得到所有副任务的结果,进而才能继续进行主任务。CountDownLatch是一个同步助手,允许一个或多个线程等待一系类的其他线程执行结束。通过观察源码,使用底层的是抽象的队列式同步器(AQS)。
Latch(门阀)设计模式该模式指定了一个屏障,只有所有的条件都得到满足,屏障才能取消,门阀才能打开。
常用方法
CountDownLatch(int count):构造方法,设置count数量,不能小于0
countDown():构造函数指定的count减1,如果此时为0,那么下次调用就会被忽略,最小只能为0
await():使得当前调用进入阻塞状态,直到count为0。当count为0时调用,会直接返回,当前线程不再阻塞
await(long timeout, TimeUnit unit):为阻塞设置超时,防止一直阻塞
getCount():获取当前count计数的值
常见场景对某些商品进行计算最终价格,由于商品涉及的模块可能不只有一个,可以采取两种方案:
串行执行,对每个商品进行一步步的任 ...
Java并发包之原子类型
基础知识Java内存模型的三个特性:
有序性:线程操作的有序性
原子性:某个操作执行的时候,整个过程要么成功,要么失败,不允许因为某些原因中断而导致部分失败或成功
可见性:线程之间的可见性,一个线程修改之后,另外一个线程也能可见
volatile关键字:只要被这个关键字修饰,从Java内存模型上来说,那么就代表该变量具有了有序性和可见性,但是还是不能保证原子性。在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制。当对非volatile变量进行读取时,一般都是从内存拷贝到CPU缓存,volatile修饰的变量,则是直接从缓存中拿取。
AtomicInteger非原子性操作:int类型的自增或者自减
1234567/** * 这个过程不是原子性的,会涉及到线程安全问题,如果要解决这个问题就需要通过synchronized关键字或者加锁才行, * 1.5版本之后,就出现了AtomicInteger等专门用来解决这个问题的工具集 */int i = 1;i++;i--;
AtomicInt ...
mqtt初探
什么是MQTTMQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。做为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
协议的特点
基于TCP协议的应用层协议
采用C/S架构
使用订阅/发布模式,将消息的发送方和接受方解耦
提供3种消息的QoS(Quality of Service):至多一次、最少一次、只有一次
收发消息都是异步的,发送方不需要等待接收方应答
MQTT协议可以为大量的低功率、工作网络不可靠的物联网设备提供通讯保障。MQTT是在低带宽高延迟不可靠的网络下进行数据相对可靠传输的应用层协议。
协议原理协议的实现方式它主要由三种身份:发布者、订阅者、代理。其中,消息的发布者和订阅者都是客户端,代理是服务端mqtt传输的消息可以分为两部分:
荷载( ...
Spring Actuator
Actuator在机器领域中,执行机构(Actuator)指的是负责控制流和移动装置的组件。在SpringBoot中,角色性质也是一致的,它主要负责组件的内部运行状态,能够在一些程度上控制应用行为。通过Actuator,我们可以获得的应用内部信息如下:
应用环境中的配置信息
各个源码包的日志级别
HTTP访问请求次数
请求的外部服务健康状况
应用消耗的内存
配置启用我们可以直接在POM文件中写入依赖
1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency>
默认情况下,我们启动应用,通过url去访问,只能够访问到health,而且也是没有任何信息的,默认的监控配置如下:
ID
JMX
Web
auditevents
Yes
No
beans
Yes
No
caches
Yes
No
...
断路器
断路器现在微服务架构当中,服务一般都是越来越多的,那么,如果出了异常,抛出错误,如果没有进行很好的处理,一般都是很难看的,而且,由于一些错误的产生可能条件很不确定,那么,要优雅的处理这些错误一定是很麻烦的。所以,现在出现了断路器的概念。
什么是断路器?如同电路断路器,保险丝一样的东西,如果出现用电功率突然增加,那么保险丝就会断了,用来保护电路,确定没问题了之后,更换保险丝,电路重新恢复正常。就如同我们的某段代码出现异常,那么断路器就会执行,就不会对错误的代码进行再次调用了。软件方面的断路器,严格来说就是一个后备程序。
软件断路器被保护的程序在给定的阀值内出现了异常,那么就可以调用一个后备方法,断路器就处于打开的状态了,以后请求就都会走这个后备方法。如果是暂时性的问题,比如网络问题,过一段时间,网络恢复了,断路器就会偶尔再去请求之前的错误方法,这个时候的状态被称为半开状态,如果方法没问题了,那么,断路器就会关闭,程序正常执行,如果依然失败,就还是开启状态。
断路器的本质通过代码的层面来看,断路器就如同一个大型的try…catch…,try里面执行代码,catch执行后备操作,但是,断路器 ...
Spring WebFlux
WebFlux简介WebFlux是Spring5之后支持的新特性。能够替代传统的SpringMVC,作为新的Web架构。它和SpringMVC非常相似,但是核心又是不同的。传统的Web框架都是阻塞、多线程,一个请求一个线程。WebFlux是Spring5引入的一个非阻塞、异步的Web框架,它是基于Reactor,能够解决Web应用和Api中对更好的扩展性的要求。WebFlux默认使用Netty作为Web服务器,Netty是一个基于NIO的框架,很适合与WebFlux一起使用。WebFlux并不是和Netty耦合在一起的,它还能选择Tomcat、Undertow、Jetty等Web服务器。WebFlux与SpringMVC系出同门,很多的核心组件都是共用的,同时也不会绑定ServletAPI,它构建在Reactive HTTP API之上,它们的功能是一直的,就是采用的是反应式的方法
WebFlux基础执行流程
处理核心类
SpringMVC
WebFlux
DispatcherServlet
DispatcherHandler
因为它与SpringMVC系出同 ...
Java基础:初始化及垃圾清理
初始化对象初始化假设存在Dog类
即使没有显式地使用 static 关键字,构造器实际上也是静态方法。所以,当首次创建 Dog 类型的对象或是首次访问 Dog 类的静态方法或属性时,Java 解释器必须在类路径中查找,以定位 Dog.class。
当加载完 Dog.class 后(后面会学到,这将创建一个 Class 对象),有关静态初始化的所有动作都会执行。因此,静态初始化只会在首次加载 Class 对象时初始化一次。
当用 new Dog() 创建对象时,首先会在堆上为 Dog 对象分配足够的存储空间。
分配的存储空间首先会被清零,即会将 Dog 对象中的所有基本类型数据设置为默认值(数字会被置为 0,布尔型和字符型也相同),引用被置为 null。
执行所有出现在字段定义处的初始化动作。
执行构造器。你将会在”复用”这一章看到,这可能会牵涉到很多动作,尤其当涉及继承的时候。
注:静态初始化只有在使用到对应的类时(在必要时),才会初始化,如果没有用到,则不会初始化
数组初始化数组并非基本类型,获取的只是它的一个引用(已分配空间),但是还没有给数组对象本身分配空间,那么就需要初始化 ...

