深入理解HashMap上篇

前言: HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。随着JDK(Java Developmet Kit)版本的更新,JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等。最近刚好有时间,刚好把HashMap相关的内容和之前做唯品会网关的一些经验整理一下。

一.HashMap的概述

1.1 HashMap的数据结构

HashMap的内存结构和原理,以及线程安全都是面试的热点问题。Java中的数据结构基本可以用数组+链表的解决。

  • 数组的优缺点:通过下标索引方便查找,但是在数组中插入或删除一个元素比较困难。
  • 链表的优缺点:由于在链表中查找一个元素需要以遍历链表的方式去查找,而插入,删除快速。因此链表适合快速插入和删除的场景,不利于查找

查看更多

Spring Cloud Gateway离开孵化器的变化

摘要: Spring Cloud对Netflix的Zuul进行封装之后,Spring Cloud Zuul作为Spring Cloud的网关一直被大家使用用至今,在Spring Cloud的核心项目开发者Spencergibb的一篇博客The API Gateway is Dead! Long Live the API Gateway!中介绍了Zuul,Zuul 2以及为什么会有Spring Cloud Gateway,大家有兴趣可以看一下。本文将会对spring-cloud-gateway-mvc源码进行demo演示和简单分析。

一.Spring Cloud Gateway概况

1.1 什么是Spring Cloud GateWay

A Gateway built on Spring Framework 5.0 and Spring Boot 2.0 providing routing and more。

Spring Cloud Gateway是基于Spring 框架5.0版本和Spring Boot 2.0的版本构建,提供路由等功能。

查看更多

Spring Cloud Zuul异常处理

最近看到了一个GitHub issue在讨论如何在post类型的zuul filter中设置response body,其中涉及到异常情况下,如何返回一个自定义的response body。正好我在升级spring-cloud,也想弄清楚,spring-cloud-zuul是如何处理异常情况的,所以就仔细看了看这部分的实现细节,现在做个笔记记录下来。

查看更多

使用Spring MVC拦截器自定义注解实现审计日志收集

前言 Spring WebMvc框架中的Interceptor,与Servlet API中的Filter十分类似,用于对Web请求进行预处理/后处理。通常情况下这些预处理/后处理逻辑是通用的,可以被应用于所有或多个Web请求,例如:

  • 记录Web请求相关日志,可以用于做一些信息监控、统计、分析
  • 检查Web请求访问权限,例如发现用户没有登录后,重定向到登录页面
  • 打开/关闭数据库连接——预处理时打开,后处理关闭,可以避免在所有业务方法中都编写类似代码,也不会忘记关闭数据库连接

查看更多

Spring Cloud项目中通过Feign进行内部服务调用发生401\407错误无返回信息的问题

前言 最近好几个小伙伴,问Spring Cloud项目中通过Feign进行内部服务调用发生401\407错误无返回信息的问题。这个问题如果没有自定义异常自定义Code或者系统中没有自定义code为401或407的code,基本很少能碰到。刚好Spring Cloud中国社区的VIP会员任聪博客原文也遇到这个,经过和他交流之后。整理出这篇文章希望能帮助更多的人快速定位问题。

查看更多

在Spring Cloud中实现降级之权重路由和标签路由

前言 限流、降级、灰度是服务治理的一个很重要的功能。本文参考Spring Cloud中国社区的VIP会员-何鹰的博客-整理
Dubbo自带服务降级、限流功能,spring cloud并没有提供此功能,只能由我们自行实现。这里的限流、降级、灰度都是针对服务实例级别,并不是整个服务级别,整个服务级别可以通过实例部署数量来实现。

限流降级设计

场景

服务A,部署了3个实例A1、A2、A3。spring cloud默认客户端负载均衡策略是采用轮询方式,A1、A2、A3三个实例流量均分,各1/3。如果这个时候需要将服务A由1.0版升级至2.0版,我们需要做的步骤是:将A1的流量降为0,柔性下线,关闭A1实例并升级到2.0,将A1流量提升为10%观察2.0线上运行情况,如果情况稳定,则逐步开放流量至不限制及1/3。依次在A2,A3上执行上述操作。
在上述步骤中,我们想让特别的人使用2.0,其他人还是使用1.0版,稳定后再全员开放。

查看更多

快速使用Spring Cloud Feign作为客户端调用服务提供者

前言 在使用Spring Cloud开发微服务应用时中,各个微服务服务提供者都是以HTTP接口的形式对外提供服务,因此服务消费者在调用服务提供者时,通过HTTP Client的方式访问。当然我们可以使用JDK原生的URLConnectionApache的Http ClientNetty的异步HTTP Client, Spring的RestTemplate去实现服务间的调用。Spring Cloud对Fegin进行了增强,使Fegin支持了Spring MVC的注解,并整合了Ribbon和Eureka,从而让Fegin的使用更加方便。

Feign简介

Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign, 可以做到使用HTTP请求远程服务时能就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。Feign的Github网址,比如:
Feign具有如下特性:

  • 可插拔的注解支持,包括Feign注解和JAX-RS注解
  • 支持可插拔的HTTP编码器和解码器
  • 支持Hystrix和它的Fallback
  • 支持Ribbon的负载均衡
  • 支持HTTP请求和响应的压缩

    查看更多

API GateWay(网关)那些儿事

前言:现在越来越多的技术团队开始尝试采纳微服务架构进行产品开发。而基于微服务架构后后端服务通常而言是动态的,为了简化前端的调用逻辑,通常会引入API Gateway作为轻量级网关,同时API Gateway中也会实现相关的认证逻辑从而简化内部服务之间相互调用的复杂度,这边文章我们就来聊聊API Gateway的那些事。
关键字:API Gateway, Spring Cloud Zuul, NginxConsulConsul-Template

为什么需要API Gateway

  • 简化客户端调用复杂度

在微服务架构模式下后端服务的实例数一般是动态的,对于客户端而言如何发现这些动态改变的服务实例的访问地址信息?因此在基于微服务的项目中为了简化前端的调用逻辑,通常会引入API Gateway作为轻量级网关,同时API Gateway中也会实现相关的认证逻辑从而简化内部服务之间相互调用的复杂度。

查看更多

Spring Cloud Zuul的URL转发和路由规则

摘要:最近开了《跟我学Spring Cloud》系列教程,由于最近比较忙,因此更新较慢。由于自己最近在研究基于Netty名为Janus的网关中间件分为janus-Server端和janus-console管控端,纳管Spring Cloud实现市面上网关85%以上的功能,将在2017年5月6号Spring Cloud中国社区北京技术沙龙分享。顺便抽时间把Spring Cloud Zuul相关的东西整理比较。在本篇文章中Spring Cloud的版本更换为Dalston.RELEASE,Spring Boot的版本为1.5.2.RELEASE。

Spring Cloud Zuul

Spring Cloud Zuul 通过与 Spring Cloud Eureka 进行整合,将自身注册到 Eureka Server中,与Eureka,Ribbon,Hystrix等整合,同时从 Eureka 中获得了所有其它微服务的实例信息。这样的设计通过把网关和服务治理整合到一起,Spring Cloud Zuul可以获取到服务注册信息,结合Ribbon,Hystrix等更好的实现路由转发,负载均衡等功能。想了解更多的内容,可以参考下面的中英文对照翻译文档。或者查看官网文档。
Spring Cloud Zuul中英文对照翻译① Spring Cloud Zuul中英文对照翻译② Spring Cloud Zuul中英文对照翻译③

查看更多

Java8编译器的新特性-参数名字保留在字节码中

摘要:很长一段时间里,Java程序员一直在发明不同的方式使得方法参数的名字能保留在Java字节码中,并且能够在运行时获取它们(比如,Paranamer类库)。最终,在Java 8中把这个强烈要求的功能添加到语言层面(通过反射API与Parameter.getName()方法)与字节码文件(通过新版的javac的–parameters选项)中。由于中间件框架使用jdk8的新特性check参数顺序和签名,因此在使用RPC框架中,RPC服务端接口定义编译后的Class文件中加入了参数,但是在webApp中使用RPC Client在Eclipse等IDE中开发调试,由于生成class的时候Ide不会自动参数带进去。因此需要对IDE进行设置。

Java编译器的新特性

参数名字

很长一段时间里,Java程序员一直在发明不同的方式使得方法参数的名字能保留在Java字节码中,并且能够在运行时获取它们(比如,Paranamer类库)。最终,在Java 8中把这个强烈要求的功能添加到语言层面(通过反射API与Parameter.getName()方法)与字节码文件(通过新版的javac的–parameters选项)中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package org.xujin.jdk.parameter;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/**
* @author xujin
*/
public class ParameterNames {
public static void main(String[] args) throws Exception {
Method method = ParameterNames.class.getMethod("main", String[].class);
for (final Parameter parameter : method.getParameters()) {
System.out.println("Parameter: " + parameter.getName());
}
}
}

查看更多