目录
从前面的学习了解到sentinel是springcloud alibaba微服务生态下的一个重要的流量治理组件,在微服务架构中占据着非常重要的地位,本篇将详细介绍下springcloud alibaba中如何整合sentinel,以及结合sentinel控制台聊聊其深入的使用。
git下载地址下载地址:
注意版本的匹配

由于是一个springboot的服务jar包,直接使用java -jar命令即可启动

启动成功后,默认端口是8080,浏览器直接:localhost:8080,默认登录账户名和密码为:sentinel /sentinel,登录之后看到下面界面,首次进入为空页面;


sentinel与springcloud-alibaba整合比较简单,按照下面的几步操作即可。
导入以下基础依赖即可
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
这里暂时没有对接其他的外部依赖,只需配置与sentinel的控制台的连接信息
server:
port: 8032
spring:
application:
name: sentinel-order
#注册中心使用nacos
cloud:
sentinel:
transport:
dashboard: localhost:8080
这里添加一个测试接口,用于接下来的各种流控规则的测试
@RestController
@RequestMapping("/order")
public class OrderController {
@GetMapping("/add")
public String add(){
System.out.println("准备下单");
return "hello " ;
}
}
启动工程后,浏览器反复调用几次接口:localhost:8032/order/add,此后在sentinel的控制台就能看到如下相关的监控信息了;

通过上面的准备,在sentinel控制台左侧呈现出了详细的规则配置菜单,接下来,结合代码分别聊聊各种配置的详细使用。
监控接口的通过的QPS和拒绝的QPS,比如我们反复刷以下add接口,就能在监控中左侧看到该接口一段时间内的调用频率趋势图,右侧的表格则更直观的记录了在具体的时间点内QPS的通过和拒绝情况;

显示微服务的所有被监控的API资源信息,比如上面的add接口在图中就呈现了出来,同时这个页面也是后续设置API接口流控规则的主要入口。
还记得在上一篇中,我们通过使用sentinel的SDK演示了各种流控规则的使用,有了sentinel的控制台之后,就变得更简单了,接下来就来详细说明下如何使用控制台的各种流控规则的配置。
其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

同一个资源可以设置多条限流规则,FlowSlot 会对该资源的所有限流规则依次遍历,直到有规则触发限流或者所有规则遍历完毕,一条限流规则主要由下面几个因素组成,我们可以组合这些元素来实现不同的限流效果;
|
|
|
|
|
|
| |
|
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 否 |
流控规则详细说明:git地址
QPS(Query Per Second)
每秒请求数,就是说服务器在一秒的时间内处理了多少个请求。
给order接口设置一个流控规则,现在每秒的请求数量上限为2;

设置完成后,界面再次快速访问时如果超过了QPS设置的阈值,将会看到下面的效果,说明配置规则生效了;

上面的规则生效后,快速刷接口时返回的提示信息是sentinel默认的一串值,如果要自定义返回信息,只需要通过@SentinelResource注解进行自定义返回值即可,如下:
@GetMapping("/add")
@SentinelResource(value = "add",blockHandler = "addBlockHandler")
public String add(){
System.out.println("准备下单");
return "hello " ;
}
public String addBlockHandler(BlockException b){
return "add 接口被流控了";
}
然后重新启动工程,再次快速刷接口时将会看到下面的效果;

并发线程数控制用于保护业务线程池不被慢调用耗尽。
例如,当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加,对于调用者来说,意味着吞吐量下降和更多的线程数占用,极端情况下甚至导致线程池耗尽。为应对太多线程占用的情况,业内有使用隔离的方案,比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢(线程池隔离)。这种隔离方案虽然隔离性比较好,但是代价就是线程数目太多,线程上下文切换的 overhead 比较大,特别是对低延时的调用有比较大的影响。
Sentinel 并发控制不负责创建和管理线程池,而是简单统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求会被立即拒绝,效果类似于信号量隔离。并发数控制通常在调用端进行配置。
新增一个接口
为了模拟出效果,给接口添加一个休眠时间,表示当前接口执行速度较慢,这样的话,当设置并发线程数时,如果第一个请求没有处理完,下一个请求过来时只能排队等待;
@GetMapping("/flow/thread")
@SentinelResource(value = "flowThread",blockHandler = "flowThreadBlockHandler")
public String flowThread(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("准备flowThread");
return "flowThread " ;
}
public String flowThreadBlockHandler(BlockException b){
return "flowThread 接口被流控了";
}
界面上为该接口配置如下流控规则,这里设置为1

保存之后,第一次请求该接口,此时,再开一个窗口再次请求该接口,将会看到如下的效果;

为了统一处理流控接口的异常,可以通过自定义全局异常类,然后在需要使用的地方引用即可
public class MyBlockException {
public static Map handleException(BlockException e){
Map<String,Object> resultMap = new HashMap<>();
if(e instanceof FlowException){
resultMap.put("code",100);
resultMap.put("msg","被限流了:" + e.getMessage());
} else if (e instanceof DegradeException) {
resultMap.put("code",101);
resultMap.put("msg","服务被降级了:" + e.getMessage());
} else if (e instanceof ParamFlowException) {
resultMap.put("code",102);
resultMap.put("msg","热点参数限流:" + e.getMessage());
} else if (e instanceof SystemBlockException) {
resultMap.put("code",103);
resultMap.put("msg","触发系统保护规则:" + e.getMessage());
} else if (e instanceof AuthorityException){
resultMap.put("code",104);
resultMap.put("msg","授权规则不通过:" + e.getMessage());
}
return resultMap;
}
}
再在需要限流的接口上通过 @SentinelResource 引用即可
@GetMapping("/add")
//@SentinelResource(value = "add",blockHandler = "addBlockHandler")
@SentinelResource(value = "add",
blockHandlerClass = MyBlockException.class,
blockHandler = "handleException")
public Map<String, Object> add() {
System.out.println("准备下单");
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("code", 200);
resultMap.put("msg", "下单成功");
return resultMap;
}
通过sentinel控制台配置一下限流规则后,再次测试以下add接口

在流控规则下面点开高级选项,可以看到流控模式这一选项,相当于是限流规则的补充;

1)基于调用关系的流量控制,调用关系包括调用方、被调用方;
2)一个方法可能会调用其它方法,形成一个调用链路的层次 关系;
从控制台可以看到提供了3钟方式,分别为:直接,关联和链路。
资源调用达到设置的阈值后直接被流控抛出异常
比如上文中设置的QPS限流,默认情况下即为直接的效果

当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联,设置了关联之后,当一个资源被限流后,这个关联的资源也将会受到影响
比如有下面两个接口,一个生成订单的接口,一个查询订单的接口,假设生成订单接口会影响到查询订单,即它们两个之间存在关联;
@GetMapping("/create")
public String createOrder(){
System.out.println("生成订单");
return "生成订单";
}
@GetMapping("/get")
public String getOrder(){
System.out.println("查询订单");
return "查询订单";
}
在sentinel控制台做如下设置

根据调用链路入口限流
比如当微服务集群中,某个微服务调用了一系列其他的微服务时,相互之间可能就构成了一棵调用树,其根节点就是起始调用的那个接口,比如:这棵树的根节点是一个名字为 getUser 的虚拟节点,调用链的入口都是这个虚节点的子节点
getUser
/ \
/ \
/ order / test1 / order / test2
上图中来自入口 /order/test1 和 /order/test2的请求都调用到了资源 getUser,Sentinel 允许只根据某个入口的统计信息对 资源限流。
新增两个接口
@Autowired
private UserService userService;
@GetMapping("/user1")
public String user1(){
return userService.getUser();
}
@GetMapping("/user2")
public String user2(){
return userService.getUser();
}
业务实现
@Service
public class UserService {
@SentinelResource(value = "getUser")
public String getUser() {
return "查询用户";
}
}
sentinel控制台设置链路,仅对来源为user2的接口进行限流


流控效果即资源被流控之后展示出来的效果,主要包括3种:
默认的流控方式,上面展示的大多数流控后的效果就是快速识别,抛出流控异常,这里不再演示。
当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。
即预热/冷启动方式。
当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过Warm Up的方式,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
sentinel控制台如下设置

测试发现,当接口刷的频率达到一定值时,将会看到被限流的效果,但不是立马被限流,而是能明显看到经历了一个过程;

也可以通过实时监控效果进一步确认当前接口的访问频率

这种方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,底层实现对应的是漏桶算法。
这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。
在sentinel的控制台做如下配置

通过压测工具访问接口,一段时间内当请求的QPS超过5个时,界面上会出现短暂的等待效果;

通过实时监控效果,也可以看出请求时间段内的QPS情况

除了流控以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。
我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。
服务的熔断、降级与隔离是保护服务自身的一种有效手段,通常在consumer端组合使用,主要实施手段有:
1)并发控制(信号量隔离);
2)基于慢调用比例熔断;
3)基于异常比例熔断;
当消费端调用的服务进行熔断后,通常可采用下面的处理逻辑:
1)提供fallback结果(服务降级);
2)返回错误result;
3)读取缓存(降低DB访问量);
|
|
|
|
|
|
| |
|
|
|
|
|
|
| |
|
|
| |
|
|
| 5 |
|
|
|
|
|
|
|
选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。
当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALFOPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断
新增一个接口,在该接口中处理需要3秒
@GetMapping("/flow/thread")
public String flowThread() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("准备flowThread");
return "flowThread ";
}
在sentinel控制台做如下配置,简单说下几个关键参数含义:

保存完毕后,可以直接在浏览器进行模拟调用,当调用的次数和频率符合了规则时,将看到下面的效果;

同时可以从实时监控效果可以看到QPS的数据;

当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。
经过熔断时长后熔断器会进入探测恢复状态(HALFOPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% 100%。
新增一个带有异常的接口
@GetMapping("/err")
public String err() {
int a = 1/0;
return "err ";
}
sentinel做如下配置

浏览器访问接口,当满足规则中的条件时将会触发熔断,出现下面的效果;

在使用openfeign进行服务调用时,对于客户端来说,被调用的服务接口出现异常时,为了消费端的服务接口不被拖垮,通常来说也需要做服务的熔断降级处理,以提升自身的稳定性,此时就可以考虑接入sentinel,接下来看看如何在openfeign中使用sentinel。
准备两个工程,第一个工程作为服务提供方,使用之前的一个扣减库存的工程,其中有一个异常接口
@GetMapping("/reduct2")
public String reduct2() {
int a=1/0;
return "扣减库存 : reduct2";
}
工程结构如下

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--nacos-discovery 注册中心-服务发现与注册-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
server:
port: 8040
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: localhost:8848 #服务注册中心地址
#config:
#server-addr: localhost:8848 #配置中心地址
sentinel:
transport:
dashboard: localhost:8080
feign:
sentinel:
enabled: true
@FeignClient(name = "stock-service",path = "/stock",fallback = FallBackService.class)
public interface StockFeignService {
@GetMapping("/reduct")
public String reduct();
@GetMapping("/reduct2")
public String reduct2();
@GetMapping("/get")
public String get(@RequestParam("id") Integer id);
}
@Component
public class FallBackService implements StockFeignService{
@Override
public String reduct() {
return null;
}
@Override
public String reduct2() {
return "服务被降级了";
}
@Override
public String get(Integer id) {
return null;
}
}
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private StockFeignService stockFeignService;
//localhost:8083/order/add
@GetMapping("/add")
public String add(){
System.out.println("下单成功");
String reduct = stockFeignService.reduct2();
return "add order :" + reduct;
}
}
启动nacos服务,启动两个工程,浏览器调用:localhost:8040/order/add,看到下面的效果

热点参数也可以理解为热点接口,即在一个系统中,那些被高频调用的接口以及某参数对应的接口,比如根据商品ID获取商品详情这样的接口在一个电商系统中一定是高频被调用的接口。
很多时候我们希望统计某个热点数据中访问频次最高的数据,并对其访问进行限制,以免被该来源的IP或应用占用太多的服务资源拖慢了整个系统的效率。
比如:热点商品的访问(访问控制),识别热点参数接口之后对来源用户/app/IP进行限制,避免防刷;
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

注意点
1)热点规则需要使用@SentinelResource("resourceName")注解,否则不生效;
2)参数必须是7种基本数据类型才会生效
@GetMapping("/get/{id}")
@SentinelResource(value = "getById",blockHandler = "hotBlockHandler")
public String getById(@PathVariable("id") Integer id){
System.out.println("正常访问");
return "正常访问" ;
}
public String hotBlockHandler(@PathVariable("id") Integer id,BlockException e){
return "热点异常处理结果" ;
}

新增完成后,在热点规则列表就有了一个数据,继续编辑

请求时设置参数为1 ,每秒1次,可以正常响应结果

每秒超过1次时,触发热点规则降级

在真实的生产环境下,对一个复杂的系统来说,引起系统故障或者突然崩溃的因素有很多,比如:
希望有个全局的兜底防护,即使一开始缺少容量评估也有一定的保护机制。简单来说就是,结合系统的指标和服务容量,能够自适应动态调整流量。
Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
Load 自适应
仅对 LinuxUnixlike 机器生效,是系统的 load1 作为启发指标,进行自适应系统保护。当系统load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。
CPU usage
当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.01.0),比较灵敏。
平均 RT
当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒
并发线程数
当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护
入口QPS
当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护
在控制台上,提供了多种系统保护规则,这里以其中的某一种为例进行说明,比如下面设置“入口QPS”,这里设置为1

删除之前配置的其他接口配置规则,快速刷新接口时,可以看到下面的效果,说明这种全局配置规则生效了。

在上面的操作中可以发现一个比较大的问题就是,一旦当工程重启,或者sentinel服务重启之后,之前界面上配置的规则就丢失了,这个并不奇怪,因为默认情况下,这些规则是动态的存储在内存中的,这在线上环境是肯定不允许的,因此为了安全起见,需要将sentine的配置规则进行持久化存储。
关于sentinel的规则持久化,官方主要提供了3种模式,分别做一一概述
API 将规则推送至客户端并直接更新到内存中,扩展写数据源(WritableDataSource),其优点就是简单无需任何依赖,缺点也很明显,重启就丢失。
扩展写数据源(WritableDataSource),客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件等,其优点就是简单无需任何依赖,缺点是不能保证一致性,实时性得不到保障,拉取过于频繁时可能存在性能问题。
pull 模式的数据源(如本地文件、RDBMS 等)一般是可写入的。使用时需要在客户端注册数据源:将对应的读数据源注册至对应的 RuleManager,将写数据源注册至 transport的WritableDataSourceRegistry 中。
扩展读数据源(ReadableDataSource),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源,其优点是,规则持久化且能保持一致性,快捷,但是需要引入第三方依赖。
生产环境下一般更常用的是 push 模式的数据源。对于 push 模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不应由 Sentinel 客户端进行,而应该经控
制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是 配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel,而不是经 Sentinel 数据源推送至配置中心。这样的流程就非常清晰了:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
下面贴出完整的配置文件内容
server:
port: 8040
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: localhost:8848 #服务注册中心地址
#config:
#server-addr: localhost:8848 #配置中心地址
sentinel:
transport:
dashboard: localhost:8080
datasource:
ds1:
nacos:
server-addr: localhost:8848
dataId: order-flow-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow
feign:
sentinel:
enabled: true
配置文件的名称即为yaml中的dataId对应的名称,选择json格式,内容如下:
[
{
"resource": "/testFlow",
"limitApp":"default",
"grade":1,
"count":1,
"strategy":0,
"controlBehavior":0,
"clusterMode":false
}
]
关于参数解释
resource:资源名称
limitApp:来源应用
grade:阀值类型,0:线程数,1:QPS
count:单机阀值
strategy:流控模式,0:直接,1:关联,2:链路
controlBehavior:流控效果,0:快速失败,1:warmUp,2:排队等待
clusterMode:是否集群
此时还未登录dashboard的情况下,快速刷接口时,可以看到如下效果,说明此时从nacos中读取到了配置规则

此时再看dashboard,可以看到这里针对该接口多了一个流控规则
重启服务,稍等一会之后,再次刷接口,再次进入dashboard进行查看流控规则,发现依然能够加载到之前从nacos中的流控规则,说明持久化规则生效了。

本文通过较大的篇幅,全方位讲述了sentinel的限流、熔断降级等规则的使用,以及如何整合springcloud进行跨服务访问使用,由于sentinel涉及到的点比较多,需要投入较多的时间和精力去研究,这对于后续在生产环境中合理使用sentinel的功能时也是一个很好的储备。
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是
目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一
开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建
文章目录概念索引相关操作创建索引更新副本查看索引删除索引索引的打开与关闭收缩索引索引别名查询索引别名文档相关操作新建文档查询文档更新文档删除文档映射相关操作查询文档映射创建静态映射创建索引并添加映射概念es中有三个概念要清楚,分别为索引、映射和文档(不用死记硬背,大概有个印象就可以)索引可理解为MySQL数据库;映射可理解为MySQL的表结构;文档可理解为MySQL表中的每行数据静态映射和动态映射上面已经介绍了,映射可理解为MySQL的表结构,在MySQL中,向表中插入数据是需要先创建表结构的;但在es中不必这样,可以直接插入文档,es可以根据插入的文档(数据),动态的创建映射(表结构),这就
HTTP缓存是指浏览器或者代理服务器将已经请求过的资源保存到本地,以便下次请求时能够直接从缓存中获取资源,从而减少网络请求次数,提高网页的加载速度和用户体验。缓存分为强缓存和协商缓存两种模式。一.强缓存强缓存是指浏览器直接从本地缓存中获取资源,而不需要向web服务器发出网络请求。这是因为浏览器在第一次请求资源时,服务器会在响应头中添加相关缓存的响应头,以表明该资源的缓存策略。常见的强缓存响应头如下所述:Cache-ControlCache-Control响应头是用于控制强制缓存和协商缓存的缓存策略。该响应头中的指令如下:max-age:指定该资源在本地缓存的最长有效时间,以秒为单位。例如:Ca
如何用IDEA2022创建并初始化一个SpringBoot项目?目录如何用IDEA2022创建并初始化一个SpringBoot项目?0. 环境说明1. 创建SpringBoot项目 2.编写初始化代码0. 环境说明IDEA2022.3.1JDK1.8SpringBoot1. 创建SpringBoot项目 打开IDEA,选择NewProject创建项目。 填写项目名称、项目构建方式、jdk版本,按需要修改项目文件路径等信息。 选择springboot版本以及需要的包,此处只选择了springweb。 此处需特别注意,若你使用的是jdk1
我正在尝试找到一种更好的方法将IRB与我的常规ruby开发集成。目前我很少在我的代码中使用IRB。我只用它来验证语法或尝试一些小的东西。我知道我可以将我自己的代码加载到ruby中作为一个require'mycode'但这通常不符合我的编程风格。有时我要检查的变量超出范围或在循环内。有没有一种简单的方法可以启动我的脚本并在IRB内的某个点卡住?我想我正在寻找一种更简单的方法来调试我的ruby代码而不破坏我的F5(编译)键。也许有经验的ruby开发者可以和我分享一个更精简的开发方法。 最佳答案 安装ruby-debugg
我开始了一个小型网络项目并使用Drupal来构建它。到目前为止,还不错:您可以快速建立一个不错的面向CMS的网站,通过模块添加社交功能,并且您有一个广泛的API可以在一个架构良好的平台中进行自定义。现在问题来了:网站的增长超出了最初的计划,我发现自己正处于认真开始为它编写代码的境地。由于Drupal项目,我对PHP有了新的认识,但我想用Ruby来做。我会感觉更舒服,以后维护起来更容易,我可以在其他Ruby/Rails应用程序中重用它。随着时间的推移,我想我会用Ruby重写Drupal中的现有部分。基于此,问题是:是否有人将两者(成功或失败的故事)结合起来?这是一个相当大的决定,但我在G