spring cloud
Eureka
先在配置文件中配置端口号以及服务名和注册中心的地址
再在主启动类上加上@EnableEurekaClent注解 配置中心相似
Ribbon
客户端负载均衡便是当浏览器向后台发出请求的时候,客户端会向 Eureka Server 读取注册到服务器的可用服务信息列表,而后根据设定的负载均衡策略(没有设置即用默认的),抉择出向哪台服务器发送请求。
在主启动类中新建一个方法,返回值为RestTemplate对象,并用@bean标签将向容器注入该方法,同时经过@LoadBalanced标签开启负载均衡的功能。
Feign
首先添加依赖
而后在主启动类上加上@EnableFeignClients 开启对Feign clent的扫描加载处理
定义Feign接口并在接口上用@FeignClients注解指定服务名和url
在controller层注入接口,当接口中的方法被调用时Feign会为每一个接口生成一个RequestTemple对象
该对象封装了HTTP请求须要的所有信息包括参数名请求方法等;
而后由RequestTemplate对象生成请求,再将请求交给Client去处理
最后Client被封装到LoadBalanceclient类,这个类结合Ribbon负载均衡发起服务间的调用。
Hystrix
在主启动类上配置@EnableCiruitBreaker断路器
而后在须要用到断路器的方法上加上@HystrixCommand注解
在括号中填入fallbackMethod=预先准备好的返回结果
Zuul
Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器.
能够用来作反向代理,也能够用来筛选和过滤请求
过滤请求:在yml中配置路由规则
nginx服务器
概念:Nginx是一个web服务器的反向代理服务器,用于HTTP、HTTPS、SMTP、POP3和IMAP协议。
特性:跨平台、配置简单、非阻塞、高并发链接、内存消耗小、性能好
用处:反向代理、负载均衡(轮询、权重、iphash)、动静分离
实现高并发原理:
一个主进程,多个工做进程,每一个工做进程能够处理多个请求,每进来一个request,会有一个worker进程去处理。遇到阻塞时,去处理其它请求,一旦上游服务器返回则触发事件,继续处理。
两个进程:
Master进程:读取及评估配置和维持
Worker进程:处理请求
配置:
server{
listen : 要监听的端口号;
server_name : 要监听的域名;
location / {
proxy_pass 须要转向的主机名和端口号;
}
}
配置负载均衡策略
upstream name{
server 主要转向的主机名和端口号;
server 主要转向的主机名和端口号;
server 主要转向的主机名和端口号;
}
经常使用的有三种策略(轮询,权重,ip_hash)
权重(server 主机名端口号+weight=n)
IPHash(在首行写ip_hash;) 每个请求固定落在一个上游服务器,可以解决ip会话在同一台服务器的问题。
fair(在尾行写fair;)配置 按上游服务器的响应时间来分配请求。响应时间短的优先分配。
url_hash配置
mycat中间件
MyCat关键特性
遵照Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理。
基于心跳的自动故障切换,支持读写分离,支持MySQL主从,支持分库分表
基于Nio实现,有效管理线程,高并发问题。java
mycat基本配置(service.xml,rule.xml,scherma.xml):
service.xml主要配置mycat服务的参数,好比端口号,myact用户名和密码使用的逻辑数据库等
role.xml主要配置路由策略、拆分规则等;
schema.xml主要配置物理数据库的信息,逻辑数据库名称以及表和路由策略之间的关系等
分库分表
水平拆分(以表为切分粒度)和垂直拆分(以行为切分粒度)
redis
支持五种数据类型(String,Hash,List,Set,zset)
String字符串:
格式: set key value
string类型是二进制安全的。意思是redis的string能够包含任何数据。好比jpg图片或者序列化的对象 。
string类型是Redis最基本的数据类型,一个键最大能存储512MB。mysql
Hash(哈希)
格式: hmset name key1 value1 key2 value2
Redis hash 是一个键值(key=>value)对集合。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。nginx
List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你能够添加一个元素到列表的头部(左边)或者尾部(右边)
格式: lpush name value
在 key 对应 list 的头部添加字符串元素
格式: rpush name value
在 key 对应 list 的尾部添加字符串元素
格式: lrem name index
key 对应 list 中删除 count 个和 value 相同的元素
格式: llen name
返回 key 对应 list 的长度web
Set(集合)
格式: sadd name value
Redis的Set是string类型的无序集合。
集合是经过哈希表实现的,因此添加,删除,查找的复杂度都是O(1)。redis
zset(sorted set:有序集合)
格式: zadd name score value
Redis zset 和 set 同样也是string类型元素的集合,且不容许重复的成员。
不一样的是每一个元素都会关联一个double类型的分数。redis正是经过分数来为集合中的成员进行从小到大的排序。
zset的成员是惟一的,但分数(score)却能够重复。
什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?
持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。
Redis 提供了两种持久化方式:RDB(默认) 和AOF
搭建redis集群:
复制多个redis
用ruby脚本语言启动reids群
用哨兵机制监控各个节点,实现高可用和自动故障迁移
哨兵机制:
用心跳检测机制去监控各个节点是否正常运行
当被监控的某个节点出现问题时, 哨兵向管理员发送通知
当一个主节点不能正常工做时,哨兵会开始一次自动故障迁移操做
自动故障迁移:
当一个主节点不能正常工做时,它会将失效的主节点的其中一个从节点升级为新的主节点
并让失效的主节点的其余从节点改成复制新的主节点;
当客户端试图链接失效的主节点时,集群也会向客户端返回新Master的地址,使得集群可使用Master代替失效Master。
什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?
缓存穿透
通常的缓存系统,都是按照key去缓存查询,若是不存在对应的value,就应该去后端系统查找(好比DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统形成很大的压力。这就叫作缓存穿透。
如何避免?
1:对查询结果为空的状况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了以后清理缓存。
2:对必定不存在的key进行过滤。能够把全部的可能存在的key放到一个大的Bitmap中,查询时经过该bitmap过滤。
缓存雪崩
当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。致使系统崩溃。
如何避免?
1:在缓存失效后,经过加锁或者队列来控制读数据库写缓存的线程数量。好比对某个key只容许一个线程查询数据和写缓存,其余线程等待。
2:作二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,能够访问A2,A1缓存失效时间设置为短时间,A2设置为长期
3:不一样的key,设置不一样的过时时间,让缓存失效的时间点尽可能均匀。spring
数据库优化
1.1尽量根据主键查询
1.2 尽量单表查询,将访问的压力交给tomcat服务器,能够经过集群的方式解决,极大减轻数据库的开销
①选择最有效率的表名顺序
数据库的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表将被最早处理
②WHERE子句中的链接顺序
数据库采用自右而左的顺序解析WHERE子句,根据这个原理,表之间的链接必须写在其余WHERE条件之左,那些能够过滤掉最大数量记录的条件必须写在WHERE子句的之右。
1.3 若是进行关联查询时,应该提前肯定数据,以后关联查询,减小笛卡尔积(关联的次数)
1.4 少用数据库函数 max/min 分组 hive
2.添加索引和视图(续表)
3.添加缓存(Redis/MemCache)
3.1非关系型数据库
3.2读写速度快,10万吞吐每秒
4.按期进行数据转储(将不用的数据,存储到历史表中(银行的流水))
5.可使用高性能非关系型数据库储存.(redis/hbase),读写速度快
6.分库分表(贵/运维)sql
数据库防止数据的丢失?
在archivelog mode(归档模式)只要其归档日志文件不丢失,就能够有效地防止数据丢失。docker
docker容器(了解) 基于 Go 语言
你可以在单台机器上运行多个Docker微容器,而每一个微容器里都有一个微服务或独立应用,例如你能够将Tomcat运行在一个Docker,而MySQL运行在另一个Docker,二者能够运行在同一个服务器,或多个服务器上。
能够直接把项目发布在DocKer容器上面进行测试,当项目须要正式上线的时候咱们直接能够把作好的DocKer 镜像部署上去就好了,DocKer能够在 云、Windows、Linux 等环境上进行部署
启动速度快数据库
solr搜索引擎
solr是基于Lucence开发的企业级搜索引擎技术,而lucence的原理是倒排索引。那么什么是倒排索引呢?接下来咱们就介绍一下lucence倒排索引原理。
提供了中文分词的功能。
schema.xml:配置域相关的信息
从数据库中导入数据:
将对应版本的mysql-connector-java.jar包放到solr的索引库目录下的lib文件夹中
在solrconfig.xml文件中配置
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
在当前目录下新建一个data-config.xml文件
在文件中导入须要放入索引库的表
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/Blog"
user="root" password="xuyiqing"/>
<document>
<entity name="user"
query="select * from blog_user" >
<field column="u_id" name="id"></field>
<field column="username" name="username"></field>
<field column="u_password" name="password"></field>
<field column="qq" name="qq"></field>
<field column="avatar" name="avatar"></field>
<field column="article_count" name="count"></field>
</entity>
</document>
</dataConfig>
最后在schema.xml中配置域:
<field name="username" type="text_ik" indexed="true" stored="true"/>
<field name="password" type="text_ik" indexed="false" stored="false"/>
<field name="qq" type="text_ik" indexed="true" stored="true"/>
<field name="avatar" type="string" indexed="false" stored="true"/>
<field name="count" type="float" indexed="true" stored="true"/>apache
rabbitMQ消息队列和kafka
好处:
能够用来解耦各个系统间的调用(解耦)
能够用来保证让系统间的调用由同步改成异步(异步)
当系统在处理高并发时,好比秒杀活动,每秒超过了2000个请求,也就时mysql的最大处理能力,若是不用消息队列的方式,系统就会死(削峰)
缺点:
系统可用性下降:系统引入的外部依赖越多,越容易挂掉,原本你就是A系统调用BCD三个系统的接口就行了,人ABCD四个系统好好的,没啥问题,你偏加个MQ进来,万一MQ挂了咋整?MQ挂了,整套系统崩溃了,你不就完了么。
系统复杂性提升:硬生生加个MQ进来,你怎么保证消息没有重复消费?怎么处理消息丢失的状况?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已
一致性问题:A系统处理完了直接返回成功了,人都觉得你这个请求就成功了;可是问题是,要是BCD三个系统那里,BD两个系统写库成功了,结果C系统写库失败了,咋整?你这数据就不一致了。
消息队列中间件:
吞吐量 时效性 可用性
ActiveMQ:万级 毫秒级
RabbitMQ:万级 延迟最低(微秒级) 基于主从架构实现
RocketMQ:10万级 毫秒级
Kafka:10万级(通常配合大数据的系统进行实时数据计算、日志采集等场景) 毫秒级之内 很是高,一个数据多个备份,少许宕机,不影响
Dubbo服务框架
Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架,现已成为 Apache 基金会孵化项目。
Dubbo和Spring Cloud的区别:
注册中心不一样,Dubbo用的是强一致性的Zookeeper,Spring Cloud 用的是Eureka
Dubbo中没有提供完善的断路器,服务网关等功能。
Dubbo支持的协议:
dubbo://(推荐) http:// rest:// redis://
Dubbo不须要Web容器
推荐使用 Zookeeper 做为注册中心,还有 Redis、Multicast、Simple 注册中心,但不推荐。
hadoop生态圈
经常使用的数据结构
商城项目
我主要是提供一些查询接口,对商品进行分类查询和模糊查询,同时在系统中调用其它服务。
物业管理系统
租凭管理模块
主要功能就是为管理员提供房产信息状态的跟踪,将不一样状态(业主在住,待出租,已出租)的房产展现给管理员,管理员可经过分类查询和模糊查询调用查询房产信息。提醒管理员近期将要到期的租凭合同以及房产信息。
管理员须要查看房产的使用状态,我用的是为房产表添加一个使用状态字段,而后根据租凭状态将信息进行分类统计;
管理员须要查看哪些租凭合同将在近一个月内过时,这就须要根据出租截止日期字段对房产信息进行查询,汇总。
租凭合同管理模块
主要是对租赁合同进行管理,合同的停止、续签、延期、做废、变动等进行管理,能够进行实时查询统计。
其实就是对租凭合同表进行增删改查。
Eureka Client:
先在配置文件中配置端口号以及服务名和注册中心的地址,而后再在主启动类上加上@EnableEurekaClent注解 配置中心相似
Feign:
首先添加依赖,而后在主启动类上加上@EnableFeignClients 开启对Feign clent的扫描加载处理,定义Feign接口并在接口上用@FeignClients注解指定服务名和url,在controller层注入接口,当接口中的方法被调用时Feign会为每一个接口生成一个RequestTemple对象,该对象封装了HTTP请求须要的所有信息包括参数名请求方法等;而后由RequestTemplate对象生成请求,再将请求交给Client去处理,最后Client被封装到LoadBalanceclient类,这个类结合Ribbon负载均衡发起服务间的调用。
Feign 工做原理
在开发微服务应用时,咱们会在主程序入口添加 @EnableFeignClients 注解开启对 Feign Client 扫描加载处理。根据 Feign Client 的开发规范,定义接口并加 @FeignClients 注解。
当程序启动时,会进行包扫描,扫描全部 @FeignClients 的注解的类,并将这些信息注入 Spring IOC 容器中。当定义的 Feign 接口中的方法被调用时,经过JDK的代理的方式,来生成具体的 RequestTemplate。当生成代理时,Feign 会为每一个接口方法建立一个 RequetTemplate 对象,该对象封装了 HTTP 请求须要的所有信息,如请求参数名、请求方法等信息都是在这个过程当中肯定的。
而后由 RequestTemplate 生成 Request,而后把 Request 交给 Client 去处理,这里指的 Client 能够是 JDK 原生的 URLConnection、Apache 的 Http Client 也能够是 Okhttp。最后 Client 被封装到 LoadBalanceclient 类,这个类结合 Ribbon 负载均衡发起服务之间的调用。
同步阻塞IO(JAVA BIO):
同步并阻塞,服务器实现模式为一个链接一个线程,即客户端有链接请求时服务器端就须要启动一个线程进行处理,若是这个链接不作任何事情会形成没必要要的线程开销,固然能够经过线程池机制改善。
同步非阻塞IO(Java NIO) : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的链接请求都会注册到多路复用器上,多路复用器轮询到链接有I/O请求时才启动一个线程进行处理。用户进程也须要时不时的询问IO操做是否就绪,这就要求用户进程不停的去询问。
异步阻塞IO(Java NIO):
此种方式下是指应用发起一个IO操做之后,不等待内核IO操做的完成,等内核完成IO操做之后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问IO是否完成,那么为何说是阻塞的呢?由于此时是经过select系统调用来完成的,而select函数自己的实现方式是阻塞的,而采用select函数有个好处就是它能够同时监听多个文件句柄(若是从UNP的角度看,select属于同步操做。由于select以后,进程还须要读写数据),从而提升系统的并发性!
(Java AIO(NIO.2))异步非阻塞IO: 在此种模式下,用户进程只须要发起一个IO操做而后当即返回,等IO操做真正的完成之后,应用程序会获得IO操做完成的通知,此时用户进程只须要对数据进行处理就行了,不须要进行实际的IO读写操做,由于真正的IO读取或者写入操做已经由内核完成了。