当前位置: 首页 > news >正文

微服务-流量染色

1. 功能目的

通过设置请求头的方式将http请求优先打到指定的服务上,为微服务开发调试工作提供便利

  1. 请求报文难模拟:可以直接在测试环境页面上操作,流量直接打到本地IDEA进行debug
  2. 请求链路较长:本地开发无需启动所有服务,仅需要启动目标服务
  3. 协同开发:与其他人一同开发,并且依赖对方开发的接口,可以直接将自己本地服务的请求发到对方本地服务上
    这是目前主要的使用目的,当然也可以调整负载均衡逻辑,配合网关的一些自定义配置,扩充为灰度发布的效果

2. 实现原理

通过在网关以及Ribbon,实现自定义的负载均衡策略,将请求引流到本地。
PS:需要服务器能访问本地,需要类似OpenVPN这样赋予本地一个IP,供服务器网关能请求到本地
开启OpenVPN之后本机会有多个IP,通过配置指定注册到nacos上的IP

spring.cloud.nacos.discovery.network-interface: 10.0

2.1 本地服务调整

本地启动时,配置文件添加参数,设置一个元数据作为服务的流量标识
比如mdm服务配置参数

spring.cloud.nacos.discovery.metadata.request-mark: azhuzhu

服务启动之后,我们可以在nacos的服务列表里看到元数据
在这里插入图片描述

2.2 网关负载均衡

服务分类:

  1. 服务器服务:metadata中没有 requestMark 参数
  2. 本地服务:metadata中带有 requestMark 参数

网关实现自定义负载均衡策略:

  • 判断请求头中是否带有本地流量标识:requestMark
    • 有标识:判断有无metadata匹配的服务实例
      • 有:调用匹配的服务实例
      • 无:判断目标请求有没有服务器服务实例
        • 有:服务器服务随机数负载
        • 无:可用实例随机负载
    • 无标识:判断目标请求有没有服务器服务实例
      • 有:服务器服务随机数负载
      • 无:可用实例随机负载
        网关负载处理了第一目标服务,假如调用链路为 mdm -> commom-api,我们启动的是common-api,则需要在服务端的ribbon中做负载
        在这里插入图片描述

2.3 请求发起

比如,约定request-mark作为本地流量标识
请求头 request-mark=azhuzhu 表示流量优先打到带有元数据 request-mark=azhuzhu 的服务

  • 浏览器操作:通过浏览器插件ModHeader,在浏览器发起请求时,带上请求头
  • HTTP工具:带上自定义请求头

3. 具体代码介绍

以下所有注册的bean, 都通过指定的配置参数开启

@ConditionalOnProperty(name = "hg.request-mark.enable", havingValue = "true")

3.1 自定义负载均衡器

网关及其他客户端的流量染色具体的负载逻辑实现

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.reactive.DefaultResponse;
import org.springframework.cloud.client.loadbalancer.reactive.EmptyResponse;
import org.springframework.cloud.client.loadbalancer.reactive.Request;
import org.springframework.cloud.client.loadbalancer.reactive.Response;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import reactor.core.publisher.Mono;import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;/*** 自定义负载均衡器 用于开发环境的流量染色** @author 阿猪 2024-08-09 11:45*/
@Slf4j
@Configuration
@SuppressWarnings("deprecation")
@ConditionalOnProperty(name = "hg.request-mark.enable", havingValue = "true")
@LoadBalancerClients(defaultConfiguration = {ReqMarkLoadBalancer.class})
public class ReqMarkLoadBalancer {public static final String REQUEST_MARK = "request-mark";/*** 开启流量染色时 替换默认的负载器** @param environment               环境信息* @param loadBalancerClientFactory 负载器工厂* @return 自定义负载器*/@Bean@Primarypublic ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}static class RandomLoadBalancer implements ReactorServiceInstanceLoadBalancer {private final ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;private final String serviceId;public RandomLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,String serviceId) {this.serviceId = serviceId;this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;}@Overridepublic Mono<Response<ServiceInstance>> choose(Request request) {ServiceInstanceListSupplier supplier =serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);String requestMark = getRequestMark(request);return supplier.get().next().map(serviceInstances -> processInstanceResponseByReqMark(serviceInstances, requestMark));}private String getRequestMark(Request<?> request) {// 客户端的负载 直接从 RequestContextHolder 拿请求头ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes != null) {return attributes.getRequest().getHeader(REQUEST_MARK);}// 网关的负载从 request 取值(网关覆盖了默认实现 把context塞进去了 不然拿到是 null 跟spring boot版本有关系)if (!(request.getContext() instanceof ServerHttpRequest)) {return null;}ServerHttpRequest context = (ServerHttpRequest) request.getContext();if (context.getHeaders().containsKey(REQUEST_MARK)) {return context.getHeaders().getFirst(REQUEST_MARK);}return null;}/*** 默认的随机数负载** @param instances 可用服务实例* @return 命中实例*/private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {if (CollectionUtils.isEmpty(instances)) {log.warn("No instance available {}", serviceId);return new EmptyResponse();}Random random = new Random();ServiceInstance instance = instances.get(random.nextInt(instances.size()));return new DefaultResponse(instance);}private Response<ServiceInstance> processInstanceResponseByReqMark(List<ServiceInstance> instances, String requestMark) {if (instances.isEmpty()) {return new EmptyResponse();}ServiceInstance sameClusterNameInst = selectInstanceByReqMark(instances, requestMark);return new DefaultResponse(sameClusterNameInst);}private ServiceInstance selectInstanceByReqMark(List<ServiceInstance> instances, String requestMark) {// 元数据不带请求标识的服务, 标识为服务器上的服务List<ServiceInstance> serverInstances = instances.stream().filter(instance -> {Map<String, String> metadata = instance.getMetadata();return MapUtils.isEmpty(metadata) || !metadata.containsKey(REQUEST_MARK);}).collect(Collectors.toList());if (StringUtils.isBlank(requestMark)) {if (CollectionUtils.isEmpty(serverInstances)) {return instances.get(new Random().nextInt(instances.size()));}return serverInstances.get(new Random().nextInt(serverInstances.size()));}List<ServiceInstance> matchInstances = Lists.newArrayList();for (ServiceInstance instance : instances) {Map<String, String> metadata = instance.getMetadata();if (MapUtils.isEmpty(metadata)) {continue;}if (metadata.containsKey(REQUEST_MARK) && requestMark.equals(metadata.get(REQUEST_MARK))) {matchInstances.add(instance);}}Random random = new Random();// 优先匹配到的服务  最后是随机if (CollectionUtils.isNotEmpty(matchInstances)) {return matchInstances.get(random.nextInt(matchInstances.size()));}// 然后是无标识服务(服务器上的服务)if (CollectionUtils.isNotEmpty(serverInstances)) {return serverInstances.get(random.nextInt(serverInstances.size()));}// 前两者都没有就随机获取return instances.get(random.nextInt(instances.size()));}}}

3.2 流量标识请求头透传

这里使用Feign进行内部服务调用,需要将原请求的流量标识 请求头继续传递下去,保证后续的服务链路也能有流量染色的效果。

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;/*** 流量染色 - 流量标识请求头透传** @author 阿猪 2024-09-25 17:11*/
@Component
@ConditionalOnProperty(name = "hg.request-mark.enable", havingValue = "true")
public class ReqMarkRequestInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate requestTemplate) {// 从 request 中获取流量标识, 设置到 feign 的 requestTemplate中ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes != null) {requestTemplate.header(ReqMarkLoadBalancer.REQUEST_MARK, attributes.getRequest().getHeader(ReqMarkLoadBalancer.REQUEST_MARK));}}}

3.3 网关负载均衡-请求信息获取

由于这个方案中,负载均衡是依靠 请求头 判断的,详见上面请求头的获取ReqMarkLoadBalancer.getRequestMark
在spring boot 2.3.2 版本中 request.getContext是个空的,没法获取请求信息
2.6.x 后面没有这个问题,但需要关注下这个context的类型,调整代码
以下是覆盖默认实现,为 request 的 context 设置请求信息。
实际上是复制 ReactiveLoadBalancerClientFilter的源码稍作修改,看倒数最后两行

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.reactive.DefaultRequest;
import org.springframework.cloud.client.loadbalancer.reactive.Request;
import org.springframework.cloud.client.loadbalancer.reactive.Response;
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter;
import org.springframework.cloud.gateway.support.DelegatingServiceInstance;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.net.URI;import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.*;/*** 覆盖默认的负载均衡器 改了choose方法 将request信息传入** @see ReactiveLoadBalancerClientFilter* @author 阿猪 2024-08-09 17:06*/
@Slf4j
@Component
@ConditionalOnProperty(name = "hg.request-mark.enable", havingValue = "true")
public class CustomLoadBalancerClientFilter extends ReactiveLoadBalancerClientFilter {private static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10150;private final LoadBalancerClientFactory clientFactory;private final LoadBalancerProperties properties;public CustomLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory,LoadBalancerProperties properties) {super(null, null);this.clientFactory = clientFactory;this.properties = properties;}@Overridepublic int getOrder() {return LOAD_BALANCER_CLIENT_FILTER_ORDER;}@Override@SuppressWarnings("Duplicates")public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);if (url == null|| (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {return chain.filter(exchange);}// preserve the original urladdOriginalRequestUrl(exchange, url);if (log.isTraceEnabled()) {log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName()+ " url before: " + url);}return choose(exchange).doOnNext(response -> {if (!response.hasServer()) {throw NotFoundException.create(properties.isUse404(),"Unable to find instance for " + url.getHost());}ServiceInstance retrievedInstance = response.getServer();URI uri = exchange.getRequest().getURI();// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,// if the loadbalancer doesn't provide one.String overrideScheme = retrievedInstance.isSecure() ? "https" : "http";if (schemePrefix != null) {overrideScheme = url.getScheme();}DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(retrievedInstance, overrideScheme);URI requestUrl = reconstructURI(serviceInstance, uri);if (log.isTraceEnabled()) {log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);}exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);}).then(chain.filter(exchange));}@SuppressWarnings("deprecation")private Mono<Response<ServiceInstance>> choose(ServerWebExchange exchange) {URI uri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);ReactorLoadBalancer<ServiceInstance> loadBalancer = this.clientFactory.getInstance(uri.getHost(), ReactorServiceInstanceLoadBalancer.class);if (loadBalancer == null) {throw new NotFoundException("No loadbalancer available for " + uri.getHost());}// 就改了这里 仅调整参数传入 保持原有逻辑(原代码传入了空的request)Request<?> request = new DefaultRequest<>(exchange.getRequest());return loadBalancer.choose(request);}}

将bean覆盖掉,替换掉原本的 ReactiveLoadBalancerClientFilter

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 流量染色 - 将ReactiveLoadBalancerClientFilter覆盖掉 为了获取到http请求头** @author 阿猪 2024-08-09 17:12*/
@Configuration
public class CustomLoadBalancerConfig {@Bean@ConditionalOnProperty(name = "hg.request-mark.enable", havingValue = "true")public ReactiveLoadBalancerClientFilter gatewayLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory,LoadBalancerProperties properties){return new CustomLoadBalancerClientFilter(clientFactory, properties);}}

相关文章:

微服务-流量染色

1. 功能目的 通过设置请求头的方式将http请求优先打到指定的服务上&#xff0c;为微服务开发调试工作提供便利 请求报文难模拟&#xff1a;可以直接在测试环境页面上操作&#xff0c;流量直接打到本地IDEA进行debug请求链路较长&#xff1a;本地开发无需启动所有服务&#xf…...

C语言实现 操作系统 经典的进程同步问题(2)

哲学家进餐问题 哲学家进餐问题是一个经典的同步问题&#xff0c;涉及多个哲学家试图同时用餐&#xff0c;但每个哲学家左右两边只有一把叉子。为了避免死锁和饥饿&#xff0c;可以使用记录型信号量&#xff08;也称为计数信号量&#xff09;来管理叉子的使用。 1、利用记录型…...

有效的字母异位词【字符串哈希】

题目 题解&#xff1a; 1.排序&#xff1a; #include<algorithm>class Solution{public:bool isAnagram(string s,string t){sort(s.begin(),s.end());sort(t.begin(),t.end());return st;} } 时间复杂度O(nlogn) 2.哈希表 #include<algorithm>int hash1[100]; …...

如何选择与运用工具提升工作效率的秘密指南

一、引言 ----  在当今这个信息爆炸的时代&#xff0c;编程工具的选择对于开发者的工作效率至关重要。从智能的代码编辑器到强大的版本控制工具&#xff0c;再到那些能让我们事半功倍的自动化脚本&#xff0c;每一款工具都有其独特的优势和价值。那么&#xff0c;哪款编程工具…...

Spring系列 AOP实现过程

文章目录 实现原理EnableAspectJAutoProxyAnnotationAwareAspectJAutoProxyCreator 代理创建过程wrapIfNecessarygetAdvicesAndAdvisorsForBeanfindCandidateAdvisorsfindAdvisorsThatCanApply createProxy AspectJ注解处理代理调用过程 实现原理 本文源码基于spring-aop-5.3.…...

C语言 getchar 函数完全解析:掌握字符输入的关键

前言 在C语言中&#xff0c;getchar 是一个非常实用的函数&#xff0c;用于从标准输入流&#xff08;通常是键盘&#xff09;读取单个字符。这对于处理文本输入非常有用&#xff0c;尤其是在需要逐个字符处理的情况下。本文将深入探讨 getchar 函数的用法和特点&#xff0c;并…...

Docker安装mysql8并配置主从复制

1. 安装mysql8 1.1 新增挂载文件 # 新增mysql挂载文件夹 mkdir -p /root/docker/mysql/m01/log mkdir -p /root/docker/mysql/m01/data mkdir -p /root/docker/mysql/m01/conf1.2 新增mysql配置文件 # 新增mysql配置文件 cd /root/docker/mysql/m01/conf vim my.cnf # 下面是…...

快手:数据库升级实践,实现PB级数据的高效管理|OceanBase案例

本文作者&#xff1a;胡玉龙&#xff0c;快手技术专家 快手在较初期采用了OceanBase 3.1版本成功替换了多个核心业务、数百套的MySQL集群。至2023年&#xff0c;快手的数据量已突破800TB大关&#xff0c;其中最大集群的数据量更是达到了数百TB级别。为此&#xff0c;快手将数据…...

基于Node.js+Express+MySQL+VUE实现的计算机毕业设计共享单车管理网站

单车信息选择骑行 骑行状态留言公告/springboot/javaWEB/J2EE/MYSQL数据库/vue前后分离小程序 目录 功能图 界面展示 开发目标 开发背景意义 开发意义‌ 开发目的 项目概述‌ 技术选型与理由‌ 系统设计与功能实现‌ 项目可执行性分析 ‌系统架构需求‌ ‌性能需…...

人工智能辅助的神经康复

人工智能辅助的神经康复是通过应用人工智能&#xff08;AI&#xff09;技术来改善神经系统损伤患者的康复过程。此领域结合了深度学习、数据分析和机器人技术&#xff0c;旨在提升康复效果、个性化治疗方案和监测进展。以下是该领域的关键组成部分和应用&#xff1a; 1. 康复评…...

KKT实际运用 -MATLAB

FMINCON函数可以很方便的求出&#xff1a;fun&#xff1a;目标函数&#xff0c;即需要最小化的函数&#xff0c;输入参数为向量x&#xff0c;输出为标量f(x)。x0&#xff1a;初始点&#xff0c;即求解过程的起始点&#xff0c;可以是标量、向量或矩阵。A和b&#xff1a;线性不等…...

php在线相册

1、将静态页面效果完成 解压到www里 整个数据 暂时是错误的 建立连接密码为root 运行sql文件 右键根目录刷新 刷新后成功 开始 测试 如果需要上传照片&#xff0c;点击创建相册&#xff0c;选择上传文件&#xff0c;选择文件后退出 导入alumbenew2 2.提交表单方式 3.利用ph…...

Xcode手动安装SDK模拟器

1.下载SDK模拟器&Xcode SDK和Xcode官方下载地址 2.下载好后使用命令将SDK导入到Xcode中如下命令 注&#xff1a;我是在/Applications 目录下执行的命令&#xff0c;模拟其地址直接拖拽过来 sudo xcode-select -s Xcode.app xcodebuild -runFirstLaunch xcodebuild -imp…...

Docker安装consul + go使用consul + consul知识

1. 什么是服务注册和发现 假如这个产品已经在线上运行&#xff0c;有一天运营想搞一场促销活动&#xff0c;那么我们相对应的【用户服务】可能就要新开启三个微服务实例来支撑这场促销活动。而与此同时&#xff0c;作为苦逼程序员的你就只有手动去 API gateway 中添加新增的这…...

JWT 漏洞 - 学习手册

0x01&#xff1a;JWT 前导知识 0x0101&#xff1a;JWT 详解 0x02&#xff1a;JWT 漏洞介绍 0x0201&#xff1a;JWT 漏洞介绍 0x03&#xff1a;JWT 挖掘思路 JWT 漏洞挖掘思路 - JWT Payload 敏感信息泄露 备注&#xff1a;通过泄露的 JWT Payload 获取用户的敏感信息&#…...

HTML【知识改变命运】03font 字体标签

题目&#xff1a;在页面上显示"北京"两个字&#xff0c;字体为微软雅黑&#xff0c;颜色为红色&#xff0c;大小为40xp&#xff1b; font标签可以修饰字体的大小&#xff0c;颜色&#xff0c;和字体 属性&#xff1a;color颜色&#xff0c;face字体&#xff0c;size大…...

集师专属知识付费小程序搭建 心理咨询小程序搭建

一、产品简介 集师SaaS知识付费软件&#xff0c;为知识创业者或商家提供一站式内容交付解决方案&#xff0c;助力商家搭建集品牌传播、商业变现和用户运营于一体的线上知识服务系统&#xff0c;覆盖全渠道经营场景&#xff0c;占据每个流量入口&#xff0c;使流量变现快速高效…...

https://www.aitoolpath.com/ 一个工具数据库,目前储存了有2000+各种工具。每日更新

AI 工具爆炸&#xff1f;别怕&#xff0c;这个网站帮你整理好了&#xff01; 哇塞&#xff0c;兄弟们&#xff01;AI 时代真的来了&#xff01;现在各种 AI 工具跟雨后春笋似的&#xff0c;噌噌噌地往外冒。AI 写作、AI 绘画、AI 代码生成……简直是要逆天啊&#xff01; 可是…...

科技的成就(六十三)

583、八小时工作制 最先提出这种理念的人竟然也是一名企业家&#xff0c;而且还是一名空想社会主义者。这名叫做罗伯特欧文的英国人&#xff0c;也凭借先进的人本管理理念成为了现代人事管理之父。 584、SDN&#xff08;软件定义网络&#xff09; "SDN&#xff08;软件定…...

浅谈抗量子密码学:保护未来的数字安全

一、引言 随着量子计算机技术的发展&#xff0c;传统的加密算法面临前所未有的挑战。量子计算机利用量子位&#xff08;qubits&#xff09;的特性&#xff0c;能够在理论上比经典计算机更快地破解现有的加密系统。为了应对这一威胁&#xff0c;研究者们正在开发所谓的“抗量子…...

10款物联网开源嵌入式操作系统对比分析

摘要 本文对目前市场上广受欢迎的10款物联网开源嵌入式操作系统进行了深度对比分析&#xff0c;包括Huawei LiteOS、RT-Thread、AliOS Things等。通过探讨这些操作系统的实时性、可扩展性、特点、运行要求、开发社区活跃度和应用领域等方面&#xff0c;帮助开发者更好地理解它…...

Elasticsearch深度攻略:核心概念与实践应用

目录 一、Elasticsearch简介1、Elasticsearch是什么2、Elasticsearch的应用场景3、Elasticsearch的核心概念 二、Elasticsearch安装与配置1、安装Elasticsearch&#xff08;1&#xff09;系统要求&#xff08;2&#xff09;下载Elasticsearch&#xff08;3&#xff09;解压安装…...

TLS详解

什么是TLS TLS(Transport Layer Security)传输层安全性协议 &#xff0c;它的前身是SSL(Secure Sockets Layer)安全套接层&#xff0c;是一个被应用程序用来在网络中安全的通讯协议&#xff0c; 防止电子邮件、网页、消息以及其他协议被篡改或是窃听。是用来替代SSL的&#xf…...

正则表达式中的特殊字符

正则表达式中的特殊字符 字符类预定义字符类量词锚点分组和捕获选择、分支和条件反义和否定转义字符示例 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 在正则表达式中&#xff0c;有许…...

EP42 公告详情页

文件路径&#xff1a; E:/homework/uniappv3tswallpaper/api/apis.js 先添加相应的api。 import {request } from "/utils/requset.js"export function apiGetBanner() {return request({url: "/homeBanner"}) } export function apiGetDayRandom() {ret…...

游戏找不到xinput1_3.dll的原因及解决方法

1. xinput1_3.dll 基本信息 1.1 文件名 xinput1_3.dll 是一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;它属于 Microsoft DirectX for Windows 的一部分。这个文件主要负责处理与 Xbox 360 控制器和其他兼容 XInput 标准的游戏手柄相关的输入信号&#xff0c;确…...

防反接电路设计

方案1 串联二极管&#xff0c; 优点&#xff1a;成本低、设计简单 缺点&#xff1a;损耗大&#xff0c;P ui 方案2 串联自恢复保险丝 当电源反接的时候&#xff0c;D4导通&#xff0c;F2超过跳闸带你留&#xff0c;就会断开&#xff0c;从而保护了后级电路 方案3 H桥电路…...

SpringMVC源码-AbstractHandlerMethodMapping处理器映射器将@Controller修饰类方法存储到处理器映射器

SpringMVC九大内置组件之HandlerMapping处理器映射器-AbstractHandlerMethodMapping类以及子类RequestMappingHandlerMapping如何将Controller修饰的注解类以及类下被注解RequestMapping修饰的方法存储到处理器映射器中。 从RequestMappingHandlerMapping寻找: AbstractHandle…...

毕业设计选题:基于ssm+vue+uniapp的购物系统小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…...

【动态规划-最长公共子序列(LCS)】力扣583. 两个字符串的删除操作

给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 示例 1&#xff1a; 输入: word1 “sea”, word2 “eat” 输出: 2 解释: 第一步将 “sea” 变为 “ea” &#xff0c;第二步将 "e…...

做配送平台网站多少钱/昆明seo案例

点击上方蓝字关注我们微信公众号&#xff1a;OpenCV学堂关注获取更多计算机视觉与深度学习知识mean.binaryproto文件生成用Caffe框架训练图像相关的视觉任务时候&#xff0c;在预处理的时候会先求图像的均值&#xff0c;这个均值其实是整个数据集的图像均值&#xff0c;Caffe中…...

惠州建设局官方网站/抖音优化公司

nk 512; k linspace(0,2*pi,nk); t 1; % 最近邻hooping U 1; % Hubbard系数 mu 0; % 化学势1/4填充取值 N 40; % N/2是对应的y方向原子个数 m 4*N; % 总的原子的个数 T 0.001; % 温度 N1avg 0…...

腾讯建站官网/陕西网站建设制作

语法弄了半天发出来备份个 --新增影城微信支付方式 create or replace procedure insert_cinema_weixin(cinema_id in varchar2 ) as cinema_name_tmp varchar2(400);begin--判断传入值是否合法if(cinema_id is null or length(cinema_id) <2) thenreturn;end if; …...

有做阿里网站的吗/百度推广销售员好做吗

OpenCV作为开源视觉库&#xff0c;整体模块的架构&#xff08;即头文件&#xff09;是核心所在。 在OpenCV-build-include文件夹下&#xff0c;有OpenCV和OpenCV 2两个文件夹&#xff0c;前者为1.0版本&#xff0c;后者为2.0版本。 以下为各模块介绍&#xff1a; 1.calib3d:相机…...

jsp网站开发四 酷 全书源码/seo技术交流论坛

1、穿透 穿透&#xff1a;频繁查询一个不存在的数据&#xff0c;由于缓存不命中&#xff0c;每次都要查询持久层。从而失去缓存的意义。 解决办法&#xff1a; 持久层查询不到就缓存空结果&#xff0c;查询时先判断缓存中是否exists(key) ,如果有直接返回空&#xff0c;没有则查…...

网站建设的主机/超级外链

PhysX 3.4更新 PhysX 3.4是一个重大更新&#xff0c;对多个方面带来了明显的改进。 首先&#xff0c;PhysX 3.4解决了大量Bug。例如&#xff1a;PhysX 3.4显著改进凸面与凸面间的碰撞检测和反馈&#xff0c;因此当启用PCM碰撞检测时&#xff0c;不会出现任何奇怪的碰撞情况。针…...