5-31面试准备

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实现,有效管理线程,高并发问题。

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。

Hash(哈希)
格式: hmset name key1 value1 key2 value2
Redis hash 是一个键值(key=>value)对集合。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。

List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
格式: lpush name value
在 key 对应 list 的头部添加字符串元素
格式: rpush name value
在 key 对应 list 的尾部添加字符串元素
格式: lrem name index
key 对应 list 中删除 count 个和 value 相同的元素
格式: llen name
返回 key 对应 list 的长度

Set(集合)
格式: sadd name value
Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

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,设置不同的过期时间,让缓存失效的时间点尽量均匀。

数据库优化
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.分库分表(贵/运维)

数据库防止数据的丢失?
在archivelog mode(归档模式)只要其归档日志文件不丢失,就可以有效地防止数据丢失。

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"/>

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读取或者写入操作已经由内核完成了。

猜你喜欢

转载自www.cnblogs.com/wanjx/p/10953074.html
今日推荐