0%

查询和过滤

elasticsearch中有查询和过滤两种功能,过滤只是用特定条件来筛选结果的,而查询不仅筛选结果还会影响文档的得分,计算得分会消耗额外的CPU

如何保证接口幂等

接口幂等是指多次发送同一个请求,保证操作执行一次

通过概念得知需要多次发送同一个请求,那么多次请求的原因有哪些

  • 多次点击提交按钮
  • 点击页面刷新
  • 使用浏览器后退按钮重复之前的操作,导致重复提交表单
  • 使用浏览器历史记录重复提交表单
  • 请求retry重试机制

针对上述情况如何解决呢?

  • 前端js提交按钮进行处理,防止重复点击
  • 使用重定向方式,使得提交表单后重定向到提交成功页面,避免用户刷新页面导致的重复提交,也可以消除浏览器前进后退导致的问题
  • session中生成一个唯一标识,请求时将唯一标识写入到表单的隐藏字段中,后端判断唯一标识与session中的是否一致,一致则说明是第一次请求,处理该请求后移除session中的标识;不相等则说明是重复请求,不进行处理
  • 使用数据库进行防止,insert时使用唯一索引,update时使用乐观锁version

Elasticsearch Java Api

elasticsearch有很多Java Api提供使用

TransportClient

使用最原始的TransportClient来进行操作

1
2
3
4
5
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.4.0</version>
</dependency>

创建TransportClient,后续操作都需要用到该对象

1
2
3
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getLocalHost(),
9300));
阅读全文 »

脑裂问题

什么是脑裂?就是同一集群中的不同节点对于集群状态有了不一样的理解,比如elasticsearch集群中有节点A(主节点),节点B(从节点),若由于网络问题两个节点之间的通信中断了,此时两个节点都认为对方已经挂了,节点A不进行任何操作,因为节点A本身就是主节点;但是节点B会将本身提升为主节点,此时就会导致elasticsearch有了两个主节点,发送到节点A上的索引请求不会将数据分配到节点B,同时发送到节点B的请求也不会将数据分配到节点A。这种情况下导致搜索请求命中哪个节点结果都不会相同

造成脑裂的原因

  • 网络问题 集群间的网络延迟导致一些节点访问不到master,认为master挂了从而选举出新的master
  • 节点负载 如果一个节点既是master又是data,当访问量过大的时候会造成es假死状态,使得其他节点得不到主节点的响应认为master挂掉了,会重新选举master

为了避免脑裂的发生,elasticsearch提供了一些配置

  • discovery.zen.minimum_master_nodes 表示决定主节点选择过程中最少需要有多少个master节点参与选举,默认是1,最好配置为N/2+1(N为候选master节点数)
  • discovery.zen.ping.timeout 节点间网络通信的等待时间,默认3s,可以调大超时时间,减少误判

跨域

何为跨域?

这就需要了解浏览器的同源策略,所谓同源是指 ‘协议+域名+端口’三者相同,而跨域就是非同源的请求

如何解决?

  • 通过代理来避免,如使用nginx在后端转发请求,来避免前端出现跨域

    在server块中增加

    1
    2
    3
    4
    5
    6
    7
    8
    # 允许跨域请求的域,*代表所有
    add_header 'Access-Control-Allow-Origin' *;
    # 允许带上cookie请求
    add_header 'Access-Control-Allow-Credentials' 'true';
    # 允许请求的方法 GET POST等
    add_header 'Access-Control-Allow-Methods' *;
    # 允许请求的header
    add_header 'Access-Control-Allow-Headers' *;
  • 使用jsonp

    浏览器的同源策略不包含<script><img><iframe>这几个标签,而jsonp就是利用<script>标签跨域特性来进行的跨域数据访问,其原理是与服务器端约定好一个函数名,服务端接收到请求后,将返回一段JavaScript,在这段JavaScript代码中调用约定好的回调函数,并且将数据作为参数进行传递,当网页接收到这段JavaScript后,就会执行回调函数,数据就成功传输到客户端了

    其缺点是只支持GET请求

  • 在web项目中配置过滤器或拦截器来解决跨域

    1
    2
    3
    4
    httpServletResponse.setHeader("Access-Control-Allow-Origin", origin);
    httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
    httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
    httpServletResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");