ElasticSearch介绍

ElasticSearch 一、 ElasticSearch介绍 Elasticsearch 是一个分布式、可扩展、实时的搜索和分析引擎,基于 Apache Lucene 构建。它能够快速存储、搜索和分析大量数据,广泛应用于全文搜索、日志分析、业务指标监控等场景。 Lucene 介绍 Lucene是开源、免费、高性能、纯Java编写的全文检索工具包 他是一个全文检索的工具包,是一个全文检索框架,并不是一个全文检索引擎 它非常复杂,并且需要Java集成使用 Lucene 和 ElasticSearch ElasticSearch和solr是基于lucene的开源项目 ElasticSearch通过简单易用的restful api接口,隐藏了lucene的复杂性 ElasticSearch自带分布式管理,并且可以跨语言使用 Lucene 和 Solr ElasticSearch自带分布式管理而Solr需要借助Zookpeeper实现分布式管理 Solr支持多格式的数据,在传统搜索中表现好于ES,但是它的更新效率比较低 ElasticSearch只支持json格式的数据,在处理实时索引搜索时明显好于Solr 二、. 核心概念 与关系型数据库的类比 关系型数据库 (MySQL) Elasticsearch Database (数据库) Index (索引) Table (表) Type (类型,已弃用) Row (行) Document (文档) Column (列) Field (字段) Schema (模式) Mapping (映射) 注意:Elasticsearch 7.x 开始移除了 Type 概念,现在一个索引直接包含文档。 1. 文档(Document) Elasticsearch 中的基本数据单元,类似于关系数据库中的一行记录。 文档以 JSON 格式存储,包含多个字段。 示例: { "id": 1, "title": "Elasticsearch Guide", "content": "Elasticsearch is a distributed search engine....

2023年07月19日 · 3 min · Leanku

PHP 8 新特性之枚举

PHP 8 新特性之枚举 枚举概览 枚举,或称 “Enum”,能够让开发者自定义类型为一系列可能的离散值中的一个。 在定义领域模型中很有用,它能够“隔离无效状态”(making invalid states unrepresentable)。 枚举以各种不同功能的形式出现在诸多语言中。 在 PHP 中, 枚举是一种特殊类型的对象。Enum 本身是一个类(Class), 它的各种条目(case)是这个类的单例对象,意味着也是个有效对象 —— 包括类型的检测,能用对象的地方,也可以用它。 最常见的枚举例子是内置的 boolean 类型, 该枚举类型有两个有效值 true 和 false。 Enum 使开发者能够任意定义出用户自己的、足够健壮的枚举。 Enum 类似 class,它和 class、interface、trait 共享同样的命名空间。 也能用同样的方式自动加载。 一个 Enum 定义了一种新的类型,它有固定、数量有限、可能的合法值。 示例 #1 用注解实现接口的可选方法 <?php // 通过传入参数:待搜索的注解类名,可返回指定的注解类, 而不需要再到反射类中迭代循环获取所有注解。 示例 <?php <?php // 声明新的枚举类型 Suit,仅有四个有效的值: Suit::Hearts、Suit::Diamonds、 Suit::Clubs、Suit::Spades。 enum Suit { case Hearts; case Diamonds; case Clubs; case Spades; } // 变量可以赋值为以上有效值里的其中一个。 函数可以检测枚举类型,这种情况下只能传入类型的值。 function pick_a_card(Suit $suit) { /* ....

2023年06月11日 · 1 min · Leanku

PHP 8 新特性之注解

PHP 8 新特性之注解功能 注解概览 注解功能提供了代码中的声明部分都可以添加结构化、机器可读的元数据的能力, 注解的目标可以是类、方法、函数、参数、属性、类常量。 通过 反射 API 可在运行时获取注解所定义的元数据。 因此注解可以成为直接嵌入代码的配置式语言。 通过注解的使用,在应用中实现功能、使用功能可以相互解耦。 某种程度上讲,它可以和接口(interface)与其实现(implementation)相比较。 但接口与实现是代码相关的,注解则与声明额外信息和配置相关。 接口可以通过类来实现,而注解也可以声明到方法、函数、参数、属性、类常量中。 因此它们比接口更灵活。 注解使用的一个简单例子:将接口(interface)的可选方法改用注解实现。 我们假设接口 ActionHandler 代表了应用的一个操作: 部分 action handler 的实现需要 setup,部分不需要。 我们可以使用注解,而不用要求所有类必须实现 ActionHandler 接口并实现 setUp() 方法。 因此带来一个好处——可以多次使用注解。 示例 #1 用注解实现接口的可选方法 <?php interface ActionHandler { public function execute(); } #[Attribute] class SetUp {} class CopyFile implements ActionHandler { public string $fileName; public string $targetDirectory; #[SetUp] public function fileExists() { if (!file_exists($this->fileName)) { throw new RuntimeException("File does not exist"); } } #[SetUp] public function targetDirectoryExists() { if (!...

2023年06月11日 · 2 min · Leanku

Consul注册中心

Consul注册中心 CAP原理 一致性(Consistency) 所有节点在同一时间具有相同的数据 可用性(Availablility) 保证每个请求不管或者失败都有响应 分区容错(Partition tolerance) 系统中任意数据的丢失或失败不会影响系统的继续运作 Consul 介绍 方便部署 采用Raft算法实现,有服务发现,key/value存储,可以做配置中心使用。有健康检查,同事提供了web管理页面 Consul角色 -dev 开发环境下的启动命令,提供基本的服务 -client 客户端,无状态的,将http和dns请求转发到服务端集群 -server 服务端,保存配置信息,可以搭建高可用的集群 Consul 内部端口 端口 说明 TCP/8300 8300端口用于服务器节点。客户端通过该端口RPC协议调用服务端接口。 TCP/UDP/8301 8301端口用于单个数据中心所有节点之间的相互通信,即对LAN池信息的同步。它使得整个数据中心能够自动发现服务器地址,分布式检测节点故障,事件广播 TCP/UDP/8302 8302端口用于单个或多个数据中心之间的服务器节点的信息同步。即对WAN池信息的同步。它针对互联网的高延迟进行了优化,能够实现跨数据中心请求。 8500 8500端口基于HTTP协议,用于API接口或WEB UI访问。 8600 8600端口作为DNS服务器,它使得我们可以通过节点名查询节点的信息。 Consul 工作原理 Consul 安装 下载地址 或者docker安装 docker run -d --name=consul -p 8500:8500 consul:1.15.4 agent -dev -client 0.0.0.0 -ui 安装完成后,命令行输入consul 检查 consul 是否可用 Consul支持web ui界面。UI可用于查看所有服务和节点,查看所有运行状况检查及其当前状态,以及读取和设置键/值数据。 用户界面自动支持多数据中心。要设置自带的UI,请使用-ui参数启动Consul代理: consul agent -ui UI可以在与HTTP API相同的端口上的/ui路径中使用。 默认情况下,这是http://localhost:8500/ui。 注册个服务 使用HTTP API 注册个服务,使用[接口API](https://www.consul.io/api/agent/service.html API)调用...

2023年06月01日 · 1 min · Leanku

常用Docker镜像

常用Docker镜像 php-msf-docker docker run --privileged --restart=always -it -d --hostname=php-msf --name=php-msf-docker -p 2202:22 -p 80:80 -p 8000:8000 -p 9501:9501 -v D:\Develop\Docker\WWW:/php-msf/data/www leanku/php-msf-docker Rabbitmq docker run -d --name rabbitmq -e RABBITMQ_DEFAULT_USER=guest -e RABBITMQ_DEFAULT_PASS=guest -p 15672:15672 -p 5672:5672 rabbitmq:3.8-management MySQL docker run -p 13306:3306 --name mysql5.7 -e MYSQL_ROOT_PASSWORD=root -v D:\Develop\Docker\app-mysql:/var/lib/mysql -d mysql:5.7 Redis docker run --name redis -p 6379:6379 -d redis redis-server --appendonly yes Elasticsearch docker run -d --name es -p 9200:9200 -p 9300:9300 -e "discovery....

2023年06月01日 · 1 min · Leanku

Redis事务和锁

Redis事务 事务是指一个完整的动作,要么全部执行,要么什么也没有做。Redis 事务不是严格意义上的事务,只是用于帮助用户在一个步骤中执行多个命令。单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。 Redis 事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。 Redis 的事务不是原子性,但是Redi执行每一个命令都是原子性的 举例:INCR在redis中是自增,即使多个客户端对同一个密钥发出INCR,也永远不会进入竞争状态。例如,客户机1读取“10”,客户机2同时读取“10”,两者都增加到11,并将新值设置为11,这样的情况永远不会发生。最终的值将始终是12。 这个案例是官网提出来的:https://redis.io/docs/data-types/tutorial/ 事务一般都是为原子性而生,既然Redis事务没有原子性,那他存在的意义是什么? redis事务的主要作用就是串联多个命令防止 别的命令插队。 官网介绍:https://redis.com.cn/redis-transaction.html Redis事务 - 基本使用 Redis 在形式上看起来也差不多,MULTI、EXEC、DISCARD这三个指令构成了 redis 事务处理的基础: MULTI:用来组装一个事务,从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,redis会将之前的命令依次执行。 EXEC:用来执行一个事务 DISCARD:用来取消一个事务 所有的指令在 exec 之前不执行,而是缓存在服务器的一个事务队列中,服务器一旦收到 exec 指令,才开执行整个事务队列,执行完毕后一次性返回所有指令的运行结果。因为 Redis 的单线程特性,不用担心自己在执行队列的时候被其它指令打搅,可以保证他们能得到的有顺序的执行。 取消事务,放弃执行事务块内的所有命令。 组队中某个命令出现了错误报告,执行时整个队列中所有的命令都会被取消。 命令组队的过程中没有问题,执行中出现了错误会导致部分成功部分失败。 悲观锁&乐观锁 悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人拿到这个数据就会block直到它拿到锁。传统的关系型数据库里面就用到了很多这种锁机制,比如行锁、表锁、读锁、写锁等,都是在做操作之前先上锁。 乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去那数据的时候都认为别人不会修改,所以不会上锁,但是在修改的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。redis就是使用这种check-and-set机制实现事务的。 watch监听 WATCH:在执行multi之前,先执行watch key1 [key2 …],可以监视一个或者多个key,若在事务的exec命令之前这些key对应的值被其他命令所改动了,那么事务中所有命令都将被打断,即事务所有操作将被取消执行。 unwatch:取消 WATCH 命令对所有 key 的监视。如果在执行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被执行了的话,那么就不需要再执行UNWATCH 了。 简单示例秒杀场景 <?php // 连接Redis $redis = new Redis(); $redis->connect('127.0.0.1',6379); $redis->watch('sales'); $sales = $redis->get('sales'); $store = 10; if($sales >= $store){ exit('结束'); } // 事务 $redis->multi(); $redis->incr('sales'); $res = $redis->exec(); if($res){ // 库存更新....

2023年05月28日 · 1 min · Leanku

JSON Web Token

JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理和用法。 一、跨域认证的问题 互联网服务离不开用户认证。一般流程是下面这样。 1、用户向服务器发送用户名和密码。 2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。 3、服务器向用户返回一个 session_id,写入用户的 Cookie。 4、用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。 5、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。 这种模式的问题在于,扩展性(scaling)不好。单机当然没有问题,如果是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都能够读取 session。 举例来说,A 网站和 B 网站是同一家公司的关联服务。现在要求,用户只要在其中一个网站登录,再访问另一个网站就会自动登录,请问怎么实现? 一种解决方案是 session 数据持久化,写入数据库或别的持久层。各种服务收到请求后,都向持久层请求数据。这种方案的优点是架构清晰,缺点是工程量比较大。另外,持久层万一挂了,就会单点失败。 另一种方案是服务器索性不保存 session 数据了,所有数据都保存在客户端,每次请求都发回服务器。JWT 就是这种方案的一个代表。 二、JWT 的原理 JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。 { “姓名”: “张三”, “角色”: “管理员”, “到期时间”: “2018年7月1日0点0分” } 以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名(详见后文)。 服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。 三、JWT 的数据结构 实际的 JWT 大概就像下面这样。 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9. TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 它是一个很长的字符串,中间用点(.)分隔成三个部分。注意,JWT 内部是没有换行的,这里只是为了便于展示,将它写成了几行。 JWT 的三个部分依次如下。 Header(头部) Payload(负载) Signature(签名) 写成一行,就是下面的样子。 Header.Payload.Signature 下面依次介绍这三个部分。...

2023年05月12日 · 2 min · Leanku

MFA

MFA 一、MFA 是什么 MFA(Multi-Factor Authentication,多因素认证) 是一种提高账户安全性的认证方式。 它要求用户在登录或进行敏感操作时提供 多种不同类别的验证因素,从而增强安全性。 通常 MFA 包含三类因素: 因素类型 描述 示例 知识因素(Something you know) 用户知道的信息 密码、PIN 持有因素(Something you have) 用户拥有的物品 手机验证码(OTP)、硬件密钥 固有因素(Something you are) 用户自身的特征 指纹、面部识别、虹膜识别 核心理念:仅凭密码不安全,增加第二甚至第三因素可以有效防止账号被盗。 二、常见应用场景 金融系统 登录网银或支付系统时,需要输入密码 + 手机短信验证码。 企业内部 SSO / VPN 登录 员工登录内部系统时,需要密码 + 动态令牌或硬件钥匙。 云服务 / SaaS 平台 如 GitHub、Google、AWS 等,用户可启用 MFA 提高账户安全。 敏感操作验证 修改密码、提现或支付等操作,需要额外的 MFA 验证。 三、MFA 的典型流程(以 TOTP 为例) 绑定 MFA 用户登录后扫描二维码绑定 MFA(生成密钥),服务器存储密钥。 生成动态验证码 用户通过 App(Google Authenticator、Authy)生成 6 位一次性验证码。 登录验证...

2023年05月12日 · 2 min · Leanku

OAuth 2.0

OAuth 2.0 一、OAuth2.0 是什么 OAuth 2.0 是一种开放标准的授权协议,用于在不暴露账号密码的情况下,让用户授权第三方应用访问其受保护的资源。 它主要解决的问题是:如何安全地委托访问权限。 核心概念: 角色 说明 资源所有者(Resource Owner) 用户或数据所有者 客户端(Client) 第三方应用,需要访问资源 授权服务器(Authorization Server) 颁发令牌的服务器,负责验证用户身份并授权 资源服务器(Resource Server) 存储用户受保护资源的服务器,验证令牌后提供数据 二、 常用场景 第三方登录(Social Login) 用户使用微信、GitHub、Google 登录你的站点,后端获取 Access Token 调用接口获取用户信息。 开放 API / 平台化 向合作伙伴提供 API,使用 OAuth 2.0 控制访问权限和作用域。 微服务内部接口调用 服务 A 调用服务 B 的接口,通过 Client Credentials 模式获取 Token,避免硬编码密码。 企业内部 SSO(单点登录) 多系统统一认证,用户在登录一次后,访问其他系统不需要重复登录。 前后端分离应用(SPA / Mobile App) 前端获取授权码,换取 Access Token,安全访问 API,密码不在前端传递。 三、OAuth 2.0 主要流程 以 授权码模式(Authorization Code Grant) 为例: 请求授权:客户端引导用户跳转到授权服务器,传入 client_id、redirect_uri、scope。...

2023年05月12日 · 2 min · Leanku

Brew 使用指南

Brew 使用指南 一、什么是 brew? 全程:Homebrew macOS(或 Linux)软件包管理器。它可以让你轻松地安装、更新、卸载软件,解决软件依赖关系,你不再需要手动下载、拖拽安装或处理复杂的编译选项。 Homebrew 会将软件包安装到独立目录,并将其文件软链接至 /opt/homebrew 。 brew官网 二、安装 Homebrew 在终端(Terminal)中执行以下命令: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 安装完成后,运行以下命令确保 Brew 工作正常: brew doctor 三、基础使用命令 1. 安装软件 安装命令行工具(Formula): brew install <formula_name> # 示例:安装 wget, tree, node brew install wget tree node 安装图形界面应用(Cask) brew install --cask <cask_name> # 示例:安装 Chrome, VS Code, Spotify brew install --cask google-chrome visual-studio-code spotify 2. 查询软件 搜索软件(不确定完整包名时非常有用): brew search <keyword> # 示例:搜索所有与 python 相关的包 brew search python 查看已安装的软件列表: brew list # 列出所有通过 Formula 安装的命令行工具 brew list --cask # 列出所有通过 Cask 安装的应用程序 查看某个软件的信息: brew info <formula_name> brew info --cask <cask_name> 3....

2023年05月11日 · 3 min · Leanku