和B+树很像,不过B+树插入需要Rebalance进行树重调整。
Mysql索引B+树
本文字数: 308 阅读时长 ≈ 1 分钟
B - 树(Balance Tree)
二叉查找树的时间复杂度是O(log(n)) 已经够快了,但是二叉查找树的查找速度取决于树的高度。
B - 树,每个节点包含最多k个孩子,k被称为阶,k的大小取决于磁盘页的大小。
一个 m 阶的 B 树具有如下几个特征
- 根节点至少有两个子女。
- 每个中间节点包含k-1个元素和k个孩子,其中m/2 <= k <= m
- 每个叶子节点都包含k-1个元素,其中 m/2 <= k <=m
- 所有叶子节点都位于同一层
- 每个节点中的元素从小到大排列,节点当中 k-1 个元素正好是 k 个孩子包含的元素的值域分划。
B+树
在b-树基础上进行改造,将索引全部建在叶子节点上,非叶子节点指向叶子节点的大小。
100块钱可以兑换50块、10块、5块、1块的算法
本文字数: 760 阅读时长 ≈ 1 分钟
最先想到的当然是for循环了:
1 | public static void main(String[] args) { |
很容易得出结果154.但是耗费时间为 1501038954420 - 1501038954413 =7;
虽然时间耗费不是很多,但是通过打印信息可以看出来,50为2的时候只有一种情况,却空跑了很多空循环。
SpringCloud学习5路由网关(zuul)
本文字数: 1.4k 阅读时长 ≈ 1 分钟
在微服务架构中,需要几个关键的组件,服务注册与发现、服务消费、负载均衡、断路器、智能路由、配置管理等,由这几个组件可以组建一个简单的微服务架构,如下图:

注意:A 服务和 B 服务是可以相互调用的,作图的时候忘记了。并且配置服务也是注册到服务注册中心的。
客户端的请求首先经过负载均衡(zuul、Ngnix),再到达服务网关(zuul 集群),然后再到具体的服务,服务统一注册到高可用的服务注册中心集群,服务的所有的配置文件由配置服务管理(下一篇文章讲述),配置服务的配置文件放在 Git 仓库,方便开发人员随时改配置。
一、Zuul 简介
Zuul 的主要功能是路由和过滤器。路由功能是微服务的一部分,比如/api/user 映射到 user 服务,/api/shop 映射到 shop 服务。zuul 实现了负载均衡。
zuul 有以下功能:
Authentication
Insights
Stress Testing
Canary Testing
Dynamic Routing
Service Migration
Load Shedding
Security
Static Response handling
Active/Active traffic management
二、准备工作
继续使用上一节的工程。在原有的工程上,创建一个新的工程。
三、创建 service-zuul 工程
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
在其入口 applicaton 类加上注解 @EnableZuulProxy,开启 zuul:
filterType:返回一个字符串代表过滤器的类型,在 zuul 中定义了四种不同生命周期的过滤器类型,具体如下:
pre:路由之前
routing:路由之时
post: 路由之后
error:发送错误调用
filterOrder:过滤的顺序
shouldFilter:这里可以写逻辑判断,是否要过滤,本文 true, 永远过滤。
run:过滤器的具体逻辑。可用很复杂,包括查 sql,nosql 去判断该请求到底有没有权限访问。
SpringCloud学习4断路器(Hystrix)
本文字数: 980 阅读时长 ≈ 1 分钟
在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC)。为了保证其高可用,单个服务又必须集群部署。由于网络原因或者自身的原因,服务并不能保证服务的 100% 可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务累计,导致服务瘫痪,甚至导致服务 “雪崩”。
为了解决这个问题,就出现断路器模型。
断路器简介
- Netflix 已经创建了一个名为 Hystrix 的库来实现断路器模式。 在微服务架构中,多层服务调用是非常常见的。
- 较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用达到一个阀值(hystric 是 5 秒 20 次) 断路器将会被打开。
- 断路打开后,可用避免连锁故障,fallback 方法可以直接返回一个固定值。
在 ribbon 使用断路器
改造 serice-ribbon 工程的代码:
在 pox.xml 文件中加入:
org.springframework.cloud spring-cloud-starter-hystrix 在程序的入口类加 @EnableHystrix:
改造 HelloService 类,加上 @HystrixCommand,并指定 fallbackMethod 方法。
Feign 中使用断路器
如果你使用了 feign,feign 是自带断路器的,并且是已经打开了。如果使用 feign 不想用断路器的话,可以在配置文件中关闭它,配置如下:
feign.hystrix.enabled=false
Circuit Breaker: Hystrix Dashboard (断路器:hystrix 仪表盘)
基于 service-ribbon 改造下:
pom.xml 加入:
org.springframework.boot spring-boot-starter-actuator <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency>
在主程序入口中加入 @EnableHystrixDashboard 注解,开启 hystrixDashboard:
该仪表盘可以查看错误率
SpringCloud学习3服务消费者feign
本文字数: 328 阅读时长 ≈ 1 分钟
使用feign
spring-cloud-starter-eureka
spring-cloud-starter-feign
spring-boot-starter-web
spring-boot-starter-test
配置文件
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8765
spring:
application:
name: service-feign
开启feign
- 在程序的入口类,需要通过注解 @EnableFeignClients 来开启 feign:
调用服务
- 定义一个 feign 接口类, 通过 @ FeignClient(“服务名”),来指定调用哪个服务:
SpringCloud学习2服务消费者
本文字数: 993 阅读时长 ≈ 1 分钟
在上一篇文章,讲了服务的注册和发现。在服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于 http restful 的。spring cloud 有两种调用方式,一种是 ribbon+restTemplate,另一种是 feign。在这一篇文章首先讲解下基于 ribbon+rest。
ribbon
是一个负载均衡客户端,可以很好的控制 http 和 tcp 的一些行为。Feign 也用到 ribbon,当你使用 @ FeignClient,ribbon 自动被应用。
ribbon 已经默认实现了这些配置 bean:
IClientConfig ribbonClientConfig: DefaultClientConfigImpl
IRule ribbonRule: ZoneAvoidanceRule
IPing ribbonPing: NoOpPing
ServerList ribbonServerList: ConfigurationBasedServerList
ServerListFilter ribbonServerListFilter: ZonePreferenceServerListFilter
ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer
准备工作
- 基于上一节的工程,启动 eureka-server 工程;启动 service-hi 工程,它的端口为 8762;将 service-hi 的配置文件的端口改为 8763, 并启动它,这时你会发现:service-hi 在 eureka-server 注册了 2 个,这就相当于一个小的集群。访问 localhost:8761 如图所示:
新建一个service-ribbon
- spring-cloud-starter-eureka
- spring-cloud-starter-ribbon
- spring-boot-starter-web
- spring-boot-starter-test
想eureka注册一个客户端
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8764
spring:
application:
name: service-ribbon
启动类
- 在工程的启动类中, 通过 @EnableDiscoveryClient 向服务中心注册;
架构如下

SpringCloud学习1EurekaServer
本文字数: 456 阅读时长 ≈ 1 分钟
创建EurekaServer
Idea初始化项目
- 选择cloud discovery->eureka server 。
创建启动类
- @EnableEurekaServer
配置参数
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
创建EurekaClient
初始化项目
- 通server
创阿金启动类
- @EnableEurekaClient
配置参数
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8762
spring:
application:
name: service-hi
微信公众平台Dubbo项目结构
本文字数: 0 阅读时长 ≈ 1 分钟
基于微信公众号的微服务架构
本文字数: 1k 阅读时长 ≈ 1 分钟
- wechatParent:
- wechat-base-parent
- wechat-business-parent
- wechat-core-parent
- wechat-web-parent
wechatParent
- 职责: 一键构建所有需要发布的项目。
- 特性
- 所有项目初始时就带有这些 jar 包的依赖,例如:testng(单元测试相关),h2(单元测试相关),easymock(单元测试相关),lombok(根据注释自动生成 setter 和 getter)
- 所有项目的额外特性,例如:单元测试插件
- 项目发布管理,例如:私一的 maven 私服配置
wechat-core-parent
- 职责:
- 该部分与业务没有关联,只提供基础能力。例如:数据库持久能力,缓存能力,http封装能力,通用工具能力。
- 通用特性:
- javadoc插件,用于生成javadoc
wechat-base-parent
- 只代表一个真实存在而且能独立存在的业务实体,简称base项目。
we-business-parent
- 职责:
- 它所聚合的的项目必须是一个提供 “共享” 业务流程,简称:business 项目。在这个流程过程中有可能需要引用 base 服务。它本身没有一个真实存在而且能独立存在的核心实体
wechat-web-parent
- 职责:
- 它所聚合的的项目可以通过互联网向用户提供服务,在产品规划上它自己独有的不被共享的业务,简称:web 项目。
总体架构图如下
Redis
- 提到阿里云的这个 Redis,不得不吐槽一句,它竟然是不支持主从的,只能单实例,不过,用它做数据缓存,还真是蛮不错的选择,响应速度非常快。而且,因为是放置在内网的且只能内网访问,所以安全性也很高。
MongoDB
- 结构型数据,主要存储档案式的数据,比如每个用户的操作行为,以档案式记录并进行统计分析,方便下一阶段的项目做个性化服务。另外一些关联复杂的数据,也可以用 MongoDb 存储,可以提高访问速度。还有,一些对软件应用版本比较敏感的数据也可以存在 MongoDB 中,比如 a 版本拿到 A 数据,b 版本拿到 B 数据,而这个 AB 数据都是由很多关联关系复杂的数据所组成,如果把这些数据根据版本号存储在不同的 MongoDB 档案中,需要时,直接根据版本号拿就可以了,这样就避免了很多的 mysql 查询。
静态资源
- OSS + CDN
OSS 存储静态资源,CDN(内容分发网络) 可以加速静态资源的下载速度。至于资源链接地址,客户端可以通过接口访问从后端业务数据库中拿到。