赞
踩
cookie和session的区别和联系:
session有什么用:
分布式session一致性:
4种分布式session解决方案:
客户端存储
缺点:
<1>数据存储在客户端,存在安全隐患
<2>cookie存储大小、类型存在限制
<3>数据存储在cookie中,如果一次请求cookie过大,会给网络增加更大的开销
session复制
缺点:
<1>session同步的原理是在同一个局域网里面通过发送广播来异步同步session的,一旦服务器多了,并发上来了,session需要同步的数据量就大了,需要将其他服务器上的session全部同步到本服务器上,会带来一定的网路开销,在用户量特别大的时候,会出现内存不足的情况
session绑定
缺点:容易造成单点故障,如果有一台服务器宕机,那么该台服务器上的session信息将会丢失 前端不能有负载均衡,如果有,session绑定将会出问题
upstream aaa {
Ip_hash;
server 39.105.59.4:8080;
Server 39.105.59.4:8081;
}
server {
listen 80;
server_name www.wanyingjing.cn;
#root /usr/local/nginx/html;
#index index.html index.htm;
location / {
proxy_pass http:39.105.59.4;
index index.html index.htm;
}
}
基于redis存储session方案
缺点:多了一次网络调用,web容器需要向redis访问
-------------引入pom依赖:------------- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-data-starter-redis</artifactId> </dependency> -------------配置redis:-------------- #redis数据库索引(默认是0) spring.redis.database=0 spring.redis.host=127.0.0.1 spring.redis.port=6379 #默认密码为空 spring.redis.password= #连接池最大连接数(负数表示没有限制) spring.redis.jedis.pool.max-active=1000 #连接池最大阻塞等待时间(负数表示没有限制) spring.redis.jedis.pool.max-wait=-1ms #连接池中的最大空闲连接 spring.redis.jedis.pool.max-idle=10 #连接池中的最小空闲连接 spring.redis.jedis.pool.min-idle=2 #连接超时时间(毫秒) spring.redis.timeout=500ms
分布式自增ID:
mysql分布式方案应用层好还是中间层好:
应用层分离:
控制上的灵活度更高,实现也简单,随时可以调整策略。但带来的问题就是增加应用层的复杂性以及额外的开发工作,均衡设置、安全防护、分流什么的,不太好加强。适合中小型项目吧,毕竟到后期的扩容方面有点麻烦。解决方案有sharding-jdbc等等
中间层分离:
专业的事还是专业的proxy来负责,应用层专心做应用层的事,中间层按规则做读写的分离。扩容均衡起来得心应手,连接池、健康切换,这样都是应用层无法实现的。适合大型超大型项目。解决方案有MyCat,Atlas等等。
MyCat简单介绍:
单纯的读写分离,此时配置最为简单,支持读写分离,主从切换;
分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片;
此外代理层解决方案还有360的Atlas
sharding-jdbc简单介绍:
适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使JDBC。
基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer和PostgreSQL。
数据分片
分库 & 分表
读写分离
分布式事务
数据库治理
两种监控工具的历史简介:
架构对比:
综合对比:
结论:如果监控的是物理机,用 Zabbix 没毛病,Zabbix在传统监控系统中,尤其是在服务器相关监控方面,占据绝对优势。甚至环境变动不会很频繁的情况下,Zabbix 也会比 Prometheus 好使;但如果是云环境的话,除非是 Zabbix 玩的非常溜,可以做各种定制,否则还是 Prometheus 吧,毕竟人家就是干这个的。Prometheus开始成为主导及容器监控方面的标配,并且在未来可见的时间内被广泛应用。如果是刚刚要上监控系统的话,不用犹豫了,Prometheus 准没错。
Grafana的介绍与使用:
Lucene:
是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构
,提供了完整的查询引擎和索引引擎,部分文本分析引擎。Solr:
Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。
Elasticsearch:
Elasticsearch跟Solr一样,也是一个基于Lucene的搜索服务器,它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulweb接口。
Elasticsearch 与 Solr 的比较:
Solr 是传统搜索应用的有力解决方案
,但 Elasticsearch 更适用于新兴的实时搜索应用。
为什么要用全文搜索引擎:
分布式锁简介:
而传统的加锁方式只针对单一架构,对于分布式架构是不适合的,这时就需要用到分布式锁。
基于 Redis 的分布式锁
基于数据库的分布式锁
基于 Zookeeper 的分布式锁
分布式锁先详解:
基于 Redis 的分布式锁:
利用 SETNX 和 SETEX。通过 SETNX 设置 Key-Value 来获得锁,随即进入死循环,每次循环判断,如果存在 Key 则继续循环,如果不存在Key,则跳出循环,当前任务执行完成后,删除 Key 以释放锁。
这种方式可能会导致死锁,为了避免这种情况,需要设置超时时间。
基于数据库的分布式锁:
基于数据库表基于 Zookeeper 的分布式锁:
ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google Chubby 的一个开源实现,是 Hadoop 和 Hbase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。分布式锁总结:
简介:
Nginx是服务器常用来做负载均衡,动静分离,反向代理的。
微服务网关有springCloud gateway,zuul,Dubbo Proxy,用做统一入口,负载均衡,动态路由。
Ribbon和Dubbo LB是内部服务调用之间的负载均衡。
Nginx与Zuul(微服务网关)区别相同点:
总结:最好建议nginx+zuul实现网关
nginx作用实现反向代理
zuul对微服务实现网关拦截
具体实现方案:
在公司中一般都是搭集群的,要么就是zuul一主一备,因为网关是统一入口如果单击版的话,网关一死直接瘫痪了.下面这个图就是让Nginx作为统一如果使用反向代理实现zuul的集群,其实下面这个图还需要加个Nginx一主一备.或者Nginx集群版就可以了.简介:
在单体架构时一般都是由一个具有暴露接口的应用+tomcat
和多个业务jar包
通过本地依赖关系调用
组成的。
①实现可以为多个springboot
②实现可以为多个ssm
当业务量骤增时,可以部署多个一样的单体架构来增加处理能力,但是当部署多个一样的架构时会使得一些公共模块冗余,例如认证授权应用,工具应用,用户管理应用等等。
①多个单体应用也就是集群应用。
这时需要将项目架构解耦,也就是使用微服务架构,这时每个应用都需要暴露出接口,对于一些公共模块例如认证授权和登录应用也只需要做一套就够了
,而对于工具类一般使用本地依赖,因为不涉及查询数据库
。各个暴露接口的应用通过rpc或rest调用。
①对于微服务架构的同一应用来说也可以做成集群架构。
总结:
①war包:
<1>war包没有页面也OK,只要有接口暴露(这个接口不是Controller层暴露,而是Service层通过RPC暴露)就行,这样就可以访问。
②jar包:
<1>同样内置tomcat的jar包也只要有接口暴露就可以访问。
<2>如果没有内置tomcat的jar包可以暴露接口(Controller层)也可以是一些工具包和依赖包而已。不过还要依赖其他jar包通过启动类启动。
③因此无论是war包还是jar包都无所谓,重要在于根据业务是否写Controlle层暴露给外部使用,对于内部调用写Controller层调用也可以,通过Service层来RPC调用也可以。
<1>Controller层的话HTTP调用
<2>Service层的话RPC调用
简述:
步骤:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
@SpringBootApplication
@EnableRetry
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Service public class RemoteService { private static final Logger logger = LoggerFactory.getLogger(TestController.class); @Retryable(value= {BusinessException.class},maxAttempts = 3,backoff = @Backoff(delay = 5000l,multiplier = 2)) public void call() throws Exception { logger.info("do something..."); throw new BusinessException("RPC调用异常"); } @Recover public void recover(BusinessException e) { logger.info(" --------------------------- "); logger.info(e.getMessage()); } }
@RestController
@RequestMapping("/test")
public class TestController {
private static final Logger logger = LoggerFactory.getLogger(TestController.class);
@Autowired
private RemoteService remoteService;
@RequestMapping("/test")
public String login() throws Exception {
remoteService.call();
return String.valueOf("11");
}
2017-07-25 19:28:07 [INFO]-[http-nio-53602-exec-1]-[com.test.retry.service.RemoteService.call(RemoteService.java:19)] do something...
2017-07-25 19:28:12 [INFO]-[http-nio-53602-exec-1]-[com.test.retry.service.RemoteService.call(RemoteService.java:19)] do something...
2017-07-25 19:28:22 [INFO]-[http-nio-53602-exec-1]-[com.test.retry.service.RemoteService.call(RemoteService.java:19)] do something...
2017-07-25 19:28:22 [INFO]-[http-nio-53602-exec-1]-[com.test.retry.service.RemoteService.recover(RemoteService.java:24)] ---------------------------
2017-07-25 19:28:22 [INFO]-[http-nio-53602-exec-1]-[com.test.retry.service.RemoteService.recover(RemoteService.java:25)] RPC调用异常
@EnableRetry能否重试。当proxyTargetClass属性为true时,使用CGLIB代理。默认使用标准JAVA注解。在spring Boot中此参数写在程序入口即可。
@Retryable 标注此注解的方法在发生异常时会进行重试。
@Backoff 重试等待策略。
@Recover 用于@Retryable重试失败后处理方法,
此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。限流简介:
缓存
、降级
和限流
。计数器
、漏桶
、令牌桶
。限流解决方案详解:
计时器算法:
在一段时间间隔内(时间窗/时间区间),处理请求的最大数量固定,超过部分不做处理。简单粗暴,比如指定线程池大小,指定数据库连接池大小、nginx连接数等,这都属于计数器算法。计数器算法是限流算法里最简单也是最容易实现的一种算法。
①缺点:
<1>这个算法虽然简单,但是有一个十分致命的问题,那就是临界问题。
<2>假设有一个恶意用户,他在0:59时,瞬间发送了100个请求,并且1:00又瞬间发送了100个请求,那么其实这个用户在 1秒里面,瞬间发送了200个请求。我们刚才规定的是1分钟最多100个请求(规划的吞吐量),也就是每秒钟最多1.7个请求,用户通过在时间窗口的重置节点处突发请求, 可以瞬间超过我们的速率限制。
<3>用户有可能通过算法的这个漏洞,瞬间压垮我们的应用。
漏斗算法:
漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。
①缺点:平时不常用,因为超过桶的容量的请求会直接被抛弃。
令牌桶算法:
最初来源于计算机网络。在网络传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送。令牌桶算法就实现了这个功能,可控制发送到网络上数据的数目,并允许突发数据的发送。大小固定的令牌桶可自行以恒定的速率源源不断地产生令牌。如果令牌不被消耗,或者被消耗的速度小于产生的速度,令牌就会不断地增多,直到把桶填满。后面再产生的令牌就会从桶中溢出。最后桶中可以保存的最大令牌数永远不会超过桶的大小。这意味,面对瞬时大流量,该算法可以在短时间内请求拿到大量令牌,而且拿令牌的过程并不是消耗很大的事情。
②优点:拿到令牌的请求去执行业务,拿不到令牌的请求可以一直等待直到获取令牌,或在一定的时间内尝试获取令牌,超时后再抛弃。
②一般来说使用令牌桶算法,Google 开源项目 Guava 中的 RateLimiter 使用的就是令牌桶控制算法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。