ElasticSearch基本使用

ElasticSearch基本使用

说明:基于 elasticsearch/elasticsearch 扩展包的 php 版使用。

文档:https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/getting-started-php.html

一、自定义服务类

php 复制代码
<?php
/**
 * Created by PhpStorm
 * User: Jason
 * Date: 2024-06-07
 * Time: 14:48
 */

require_once '../vendor/autoload.php';

use Elasticsearch\ClientBuilder;

class ES
{
    /**
     * 客户端
     *
     * @var \Elasticsearch\Client
     */
    private $client;

    /**
     * @param array $hosts
     */
    public function __construct(array $hosts = ['127.0.0.1'])
    {
        $this->client = ClientBuilder::create()->setHosts($hosts)->build();
    }

    // ================================= 索引相关操作 =================================================

    /**
     * 创建索引
     * 说明:相当于Mysql的表,只需要创建一次;原本相当于database,8.x废除了type(相当于table)
     *
     * @param string $index 索引名称
     * @param array $settings 索引设置
     * @param array $mappings 索引映射
     * @return array
     */
    public function creatIndex(string $index, array $settings = [], array $mappings = []): array
    {
        $params = [
            'index' => $index,
            'body' => [
                'settings' => $settings,
                'mappings' => $mappings,
            ]
        ];

        return $this->client->indices()->create($params);
    }

    /**
     * 删除索引
     *
     * @param $indexName string 索引名称
     * @return array
     */
    public function deleteIndex(string $indexName): array
    {
        $params = [
            'index' => $indexName,
        ];

        return $this->client->indices()->delete($params);
    }

    /**
     * 检查索引是否存在
     *
     * @param string $indexName
     * @return bool
     */
    public function existsIndex(string $indexName)
    {
        return $this->client->indices()->exists(['index' => $indexName]);
    }

    /**
     * 获取索引设置
     *
     * @param string $indexName 索引名称
     * @return array
     */
    public function getIndexSettings(string $indexName): array
    {
        $params = [
            'index' => $indexName
        ];

        return $this->client->indices()->getSettings($params);
    }

    /**
     * 关闭索引
     *
     * @param $indexName string 索引名称
     * @return array
     */
    public function closeIndex(string $indexName): array
    {
        $params = ['index' => $indexName];

        return $this->client->indices()->close($params);
    }

    /**
     * 打开索引
     *
     * @param $indexName string 索引名称
     * @return array
     */
    public function openIndex(string $indexName): array
    {
        $params = ['index' => $indexName];

        return $this->client->indices()->open($params);
    }

    /**
     * 更新索引设置
     *
     * @param string $indexName 索引名称
     * @param array $settings 新的索引设置
     * @return array 更新索引设置的响应
     */
    public function updateIndexSettings(string $indexName, array $settings): array
    {
        $params = [
            'index' => $indexName,
            'body' => ['settings' => $settings]
        ];

        return $this->client->indices()->putSettings($params);
    }

    /**
     * 更新非动态索引设置
     *
     * @param $indexName string 索引名称
     * @param array $settings 索引设置
     * @return array
     */
    public function updateNonDynamicIndexSettings(string $indexName, array $settings)
    {
        // 关闭索引
        $this->closeIndex($indexName);

        // 更新索引设置
        $response = $this->updateIndexSettings($indexName, $settings);

        // 重新打开索引
        $this->openIndex($indexName);

        return $response;
    }

    /**
     * 获取索引映射
     *
     * @param string $indexName 索引名称
     * @return array 获取索引映射的响应
     */
    public function getIndexMappings($indexName)
    {
        $params = [
            'index' => $indexName
        ];

        return $this->client->indices()->getMapping($params);
    }

    /**
     * 更新索引映射
     *
     * @param string $indexName 索引名称
     * @param array $mappings 新的索引映射
     * @return array 更新索引映射的响应
     */
    public function updateIndexMappings(string $indexName, array $mappings): array
    {
        $params = [
            'index' => $indexName,
            'body' => ['properties' => $mappings]
        ];

        return $this->client->indices()->putMapping($params);
    }

    /**
     * 刷新索引
     *
     * @param $indexName string 索引名称
     * @return array
     */
    public function refreshIndex(string $indexName): array
    {
        $params = [
            'index' => $indexName
        ];

        return $this->client->indices()->refresh($params);
    }

    // ===================================== 文档相关操作 ===============================================

    /**
     * 新增文档
     *
     * @param string $indexName 索引名称
     * @param string $id 文档ID
     * @param array $body 文档内容
     * @return array
     */
    public function addDocument($indexName, string $id, array $body)
    {
        $params = [
            'index' => $indexName,
            'id' => $id, // 文档ID,可省略,默认生成随机ID
            'body' => $body
        ];

        return $this->client->index($params);
    }

    /**
     * 批量新增文档
     *
     * @param array $params
     * @return array|callable
     */
    public function batchAddDocument(array $params)
    {
        return $this->client->bulk($params);
    }

    /**
     * 获取文档
     * 说明:查询单挑记录
     *
     * @param string $indexName 索引名称
     * @param string $id 文档ID
     * @return array|callable
     */
    public function getDocument(string $indexName, string $id): callable|array
    {
        $params = [
            'index' => $indexName,
            'id' => $id,
        ];

        return $this->client->get($params);
    }

    /**
     * 更新文档
     *
     * @param string $indexName 索引名称
     * @param string $id 文档ID
     * @param array $doc 更新内容
     * @return array|callable
     */
    public function updateDocument(string $indexName, string $id, array $doc)
    {
        $params = [
            'index' => $indexName,
            'id' => $id,
            'body' => [
                'doc' => $doc, // 需要更新的内容
            ],
        ];

        return $this->client->update($params);
    }

    /**
     * 删除文档
     *
     * @param string $indexName
     * @param $id
     * @return array|callable
     */
    public function deleteDocument(string $indexName, $id)
    {
        $params = [
            'index' => $indexName,
            'id' => $id,
        ];

        return $this->client->delete($params);
    }

    // ======================================= 搜索相关操作 ================================================

    /**
     * 基础搜索方法
     *
     * @param string $indexName 索引名称
     * @param array $query 搜索查询
     * @param array|null $sort 排序参数
     * @param int|null $from 起始位置
     * @param int|null $size 返回结果数
     * @return array
     */
    public function search(string $indexName, array $query, array $sort = null, int $from = null, int $size = null)
    {
        $params = [
            'index' => $indexName,
            'body' => [
                'query' => $query
            ]
        ];

        if ($sort) {
            $params['body']['sort'] = $sort;
        }

        if (!is_null($from)) {
            $params['body']['from'] = $from;
        }

        if (!is_null($size)) {
            $params['body']['size'] = $size;
        }

        return $this->client->search($params);
    }
}

二、索引基本使用

2.1 创建索引

php 复制代码
<?php
$hosts = [
    '192.168.0.117:9200'
];

$es = new ES($hosts);

// 索引名
$userIndex = 'user';

// 设置
$settings = [
    // 分片数量: 一个索引库将拆分成多片分别存储不同的结点,默认5个
    'number_of_shards' => count($hosts),
    // 每个分片分配的副本数,replica shard是primary shard的副本,负责容错,以及承担读请求负载,如果服务器只有一台,只能设置为0
    'number_of_replicas' => 0
];

// 创建文档映射,就是文档存储在ES中的数据结构
$mappings = [
    'properties' => [
        'user_id' => [
            'type' => 'integer',
            'index' => 'true'
        ],
        'nickname' => [
            // 数据类型: text支持分词; keyword不支持分词,只能精确索引;数值类型(integer,...),日期类型(date),逻辑类型:boolean;IP类型(ip);地理坐标类型(geo_point);.....
            // keyword 排序是按照字符串的ASCII码排序的,'3'>'20'
            'type' => 'text',
            // 字段可以被索引,也就是能用来当做查询条件来查询,只能填写true和false
            'index' => 'true',
            // 索引分词器,用于字符串类型,这里使用中文分词器ik,用默认分词器可以省略
            'analyzer' => 'ik_max_word',
            // 搜索分词器,用于搜索关键词的分词器
            'search_analyzer' => 'ik_max_word',
        ],
        'age' => [
            'type' => 'integer',
            'index' => 'true',
        ],
        'create_time' => [
            'type' => 'date',
            'index' => 'true',
            'format' => 'yyyy-MM-dd HH:mm:ss'
        ],
    ]
];

$res = $es->creatIndex($userIndex, $settings, $mappings);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"acknowledged":true,"shards_acknowledged":true,"index":"user"}

2.2 判断索引是否存在

php 复制代码
<?php
$res = $es->existsIndex($userIndex);
var_dump($res); 
// 输出: true

2.3 删除索引

php 复制代码
<?php
$res = $es->deleteIndex($userIndex);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"acknowledged":true}

2.4 获取索引设置

php 复制代码
<?php
$res = $es->getIndexSettings($userIndex);
var_dump(json_encode($res,JSON_UNESCAPED_UNICODE)); 
// 输出: {"user":{"settings":{"index":{"routing":{"allocation":{"include":{"_tier_preference":"data_content"}}},"refresh_interval":"1s","number_of_shards":"1","provided_name":"user","creation_date":"1719907928617","number_of_replicas":"0","uuid":"7d3Mojg6SL6q_7Q0gamMog","version":{"created":"8503000"}}}}}

2.5 更新索引设置

php 复制代码
<?php
$settings = [
    'index.refresh_interval' => '1s' // 刷新时间间隔
];
$res = $es->updateNonDynamicIndexSettings($userIndex, $settings);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"acknowledged":true}

2.6 获取索引映射

php 复制代码
<?php
$res = $es->getIndexMappings($userIndex);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"user":{"mappings":{"properties":{"age":{"type":"integer"},"create_time":{"type":"date","format":"yyyy-MM-dd HH:mm:ss"},"nickname":{"type":"text","analyzer":"ik_max_word"},"user_id":{"type":"integer"}}}}}

2.7 更新索引映射

php 复制代码
<?php
$mappings = [
    'phone' => [
        'type' => 'keyword',
        'index' => 'true'
    ]
];
$res = $es->updateIndexMappings($userIndex, $mappings);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"acknowledged":true}

2.8 刷新索引

php 复制代码
<?php
$res = $es->refreshIndex($userIndex);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出:  {"_shards":{"total":1,"successful":1,"failed":0}}

三、文档基本使用

3.1 新增文档

php 复制代码
<?php
$res = $es->addDocument($userIndex, '1', [
    'user_id' => 1,
    'nickname' => '爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)',
    'age' => mt_rand(10, 40),
    'create_time' => \Carbon\Carbon::now()->toDateTimeString(),
    'phone' => '13612348888'
]);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"_index":"user","_id":"1","_version":1,"result":"created","_shards":{"total":1,"successful":1,"failed":0},"_seq_no":0,"_primary_term":5}

3.2 批量新增文档

php 复制代码
<?php
$documents = [
    [
        'user_id' => 2,
        'nickname' => '高颜值情侣玻璃浮雕吸管杯2个-xh',
        'age' => 12,
        'create_time' => '2024-06-29 12:00:05',
        'phone' => '13575861234',
    ],
    [
        'user_id' => 3,
        'nickname' => '网红爆款护手霜6支香味随机-K',
        'age' => 23,
        'create_time' => '2024-06-28 03:18:08',
        'phone' => '19512345286',
    ],
    [
        'user_id' => 4,
        'nickname' => '【可拆卸一拖四线】充电宝迷你自带线大容量数显快充移动电源',
        'age' => 34,
        'create_time' => '2024-07-02 03:18:08',
        'phone' => '19538883347',
    ],
];

$params = [];
foreach ($documents as $document) {
    $params['body'][] = [
        'index' => [
            '_index' => $userIndex,
            '_id' => strval($document['user_id'])
        ]
    ];

    $params['body'][] = [
        'user_id' => $document['user_id'],
        'nickname' => $document['nickname'],
        'age' => $document['age'],
        'create_time' => $document['create_time'],
        'phone' => $document['phone'],
    ];
}
var_dump(json_encode($es->batchAddDocument($params), JSON_UNESCAPED_UNICODE)); 
// 输出: {"errors":false,"took":15,"items":[{"index":{"_index":"user","_id":"2","_version":1,"result":"created","_shards":{"total":1,"successful":1,"failed":0},"_seq_no":3,"_primary_term":5,"status":201}},{"index":{"_index":"user","_id":"3","_version":1,"result":"created","_shards":{"total":1,"successful":1,"failed":0},"_seq_no":4,"_primary_term":5,"status":201}},{"index":{"_index":"user","_id":"4","_version":1,"result":"created","_shards":{"total":1,"successful":1,"failed":0},"_seq_no":5,"_primary_term":5,"status":201}}]}

3.3 获取文档

php 复制代码
<?php
var_dump(json_encode($es->getDocument($userIndex, '9'), JSON_UNESCAPED_UNICODE)); 
// 输出: {"_index":"user","_id":"1","_version":3,"_seq_no":2,"_primary_term":5,"found":true,"_source":{"user_id":1,"nickname":"爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)","age":29,"create_time":"2024-07-02 17: 15: 16","phone":"13612348888"}}

3.4 更新文档

php 复制代码
<?php
$res = $es->updateDocument($userIndex, '1', [
    'nickname' => '9999Jason的爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)',
    'age' => 30
]);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"_index":"user","_id":"1","_version":2,"result":"updated","_shards":{"total":1,"successful":1,"failed":0},"_seq_no":7,"_primary_term":5}

3.5 删除文档

php 复制代码
<?php
$res = $es->deleteDocument($userIndex, '9');
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE));
// 输出: {"_index":"user","_id":"9","_version":3,"result":"deleted","_shards":{"total":1,"successful":1,"failed":0},"_seq_no":8,"_primary_term":5}

四、文档搜索

4.1 词条匹配查询(精确匹配查询): 类似 where age = xx

php 复制代码
<?php
$query = [
    'term' => [
        'age' => 34
    ]
];
$res = $es->search($userIndex, $query);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"took":2,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":2,"relation":"eq"},"max_score":null,"hits":[{"_index":"user","_id":"4","_score":null,"_source":{"user_id":4,"nickname":"【可拆卸一拖四线】充电宝迷你自带线大容量数显快充移动电源","age":34,"create_time":"2024-07-02 03: 18: 08","phone":"19538883347"},"sort":[1719890288000,4]}]}}

4.2 多条件查询 : 类似 where xxx and xxx

php 复制代码
<?php
$query = [
    'bool' => [
        'must' => [
            [
                'term' => [
                    'age' => 29
                ],
            ],
            [
                'term' => [
                    'phone' => '13612348888'
                ],
            ]
        ]
    ]
];
$res = $es->search($userIndex, $query);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); // 输出: {"took":1,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":2.3862944,"hits":[{"_index":"user","_id":"1","_score":2.3862944,"_source":{"user_id":1,"nickname":"爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)","age":29,"create_time":"2024-07-02 17:15:16","phone":"13612348888"}}]}}

4.3 通配符查询

说明:对于keyword等不支持分词的类型,模糊查询使用通配符(wildcard)查询;

php 复制代码
<?php
$query = [
    'wildcard' => [
        "nickname" => '*肉松*' // 使用 * 作为通配符,* 可以匹配任意字符序列(包括空字符序列)。例如,*elastic* 可以匹配 elastic 、my elastic search 、elasticity 等
    ]
];
$res = $es->search($userIndex, $query);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"took":3,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":2,"relation":"eq"},"max_score":1,"hits":[{"_index":"user","_id":"1","_score":1,"_source":{"user_id":1,"nickname":"爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)","age":29,"create_time":"2024-07-02 17: 15: 16","phone":"13612348888"}},{"_index":"user","_id":"5","_score":1,"_source":{"user_id":5,"nickname":"爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)","age":34,"create_time":"2024-07-03 09: 28: 29","phone":"19575621495"}}]}}

4.4 模糊查询

说明:对于text等支持分词的类型,推荐使用fuzzy进行模糊查询

php 复制代码
<?php
$query = [
    'fuzzy' => [
        "nickname" => [
            'value' => '肉松',
            'fuzziness' => 1 // fuzziness 参数指定了允许的模糊程度。值越大,允许的差异越大。例如,fuzziness: 2 可能允许一些字符的替换、插入或删除
        ]
    ]
];
$res = $es->search($userIndex, $query);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"took":3,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":2,"relation":"eq"},"max_score":0.8915597,"hits":[{"_index":"user","_id":"1","_score":0.8915597,"_source":{"user_id":1,"nickname":"爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)","age":29,"create_time":"2024-07-02 17: 15: 16","phone":"13612348888"}},{"_index":"user","_id":"5","_score":0.8915597,"_source":{"user_id":5,"nickname":"爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)","age":34,"create_time":"2024-07-03 09: 28: 29","phone":"19575621495"}}]}}

4.5 前缀查询

说明: 前缀查询通常适用于keyword类型的字段,这种类型的字段不会进行分词处理,会将整个值作为一个词条来建立索引

php 复制代码
<?php
$query = [
    'prefix' => [
        "phone" => '195'
    ]
];
$res = $es->search($userIndex, $query);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"took":3,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":3,"relation":"eq"},"max_score":1,"hits":[{"_index":"user","_id":"3","_score":1,"_source":{"user_id":3,"nickname":"网红爆款护手霜6支香味随机-K","age":23,"create_time":"2024-06-28 03: 18: 08","phone":"19512345286"}},{"_index":"user","_id":"4","_score":1,"_source":{"user_id":4,"nickname":"【可拆卸一拖四线】充电宝迷你自带线大容量数显快充移动电源","age":34,"create_time":"2024-07-02 03: 18: 08","phone":"19538883347"}},{"_index":"user","_id":"5","_score":1,"_source":{"user_id":5,"nickname":"爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)","age":34,"create_time":"2024-07-03 09: 28: 29","phone":"19575621495"}}]}}

4.6 联合查询 - and

SQL: where age in (23,34) and create_time between 2024-07-01 00:00:00 and 2024-07-02 23:59:59

php 复制代码
<?php
$query = [
    'bool' => [
        // must(且): 数组里面的条件都要满足,该条数据才会被选择
        'must' => [
            [
                'terms' => [
                    'age' => [23, 34] // 类似于 where in
                ]
            ],
            [
                'range' => [ // 类似 between
                    'create_time' => [
                        'gte' => '2024-07-01 00:00:00',
                        'lte' => '2024-07-02 23:59:59',
                    ]
                ]
            ]
        ]
    ]
];
$res = $es->search($userIndex, $query);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE)); 
// 输出: {"took":3,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":2,"hits":[{"_index":"user","_id":"4","_score":2,"_source":{"user_id":4,"nickname":"【可拆卸一拖四线】充电宝迷你自带线大容量数显快充移动电源","age":34,"create_time":"2024-07-02 03: 18: 08","phone":"19538883347"}}]}}

4.7 联合查询 - or

SQL: where (age <=18 or age >=34) and between 2024-07-01 00:00:00 and 2024-07-02 23:59:59

php 复制代码
<?php
$query = [
    'bool' => [
        "must" => [
            [
                'range' => [
                    'create_time' => [
                        'gte' => '2024-06-29 00:00:00',
                        'lte' => '2024-07-02 04:00:00',
                    ]
                ]
            ]
        ],
        // should(或): 数组里面的条件满足其中一个,该条数据被选择
        "should" => [
            [
                'range' => [
                    'age' => [
                        'lte' => 18,
                    ]
                ]
            ],
            [
                'range' => [
                    'age' => [
                        'gte' => 34,
                    ]
                ]
            ]
        ]
    ]
];
$res = $es->search($userIndex, $query);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE));
 // 输出: {"took":2,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":2,"relation":"eq"},"max_score":2,"hits":[{"_index":"user","_id":"2","_score":2,"_source":{"user_id":2,"nickname":"高颜值情侣玻璃浮雕吸管杯2个-xh","age":12,"create_time":"2024-06-29 12: 00: 05","phone":"13575861234"}},{"_index":"user","_id":"4","_score":2,"_source":{"user_id":4,"nickname":"【可拆卸一拖四线】充电宝迷你自带线大容量数显快充移动电源","age":34,"create_time":"2024-07-02 03: 18: 08","phone":"19538883347"}}]}}

4.8 联合查询 - or and or

SQL: where (age >= 34 or age <= 18) and (create_time >= '2024-07-02 00:00:00' or create_time <= '2024-06-30 00:00:00')

php 复制代码
<?php
# 联合查询
$query = [
    'bool' => [
        'must' => [
            [
                'bool' => [
                    'should' => [
                        [
                            'range' => [
                                'age' => [
                                    'lte' => 18,
                                ]
                            ]
                        ],
                        [
                            'range' => [
                                'age' => [
                                    'gte' => 34,
                                ]
                            ]
                        ]
                    ]
                ]
            ],
            [
                'bool' => [
                    'should' => [
                        [
                            'range' => [
                                'create_time' => [
                                    'lte' => '2024-06-30 00:00:00',
                                ]
                            ]
                        ],
                        [
                            'range' => [
                                'create_time' => [
                                    'gte' => '2024-07-02 00:00:00',
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];
$res = $es->search($userIndex, $query);
var_dump(json_encode($res, JSON_UNESCAPED_UNICODE));
相关推荐
JaguarJack2 小时前
为什么 PHP 闭包要加 static?
后端·php·服务端
ServBay1 天前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
洛森唛1 天前
ElasticSearch查询语句Query String详解:从入门到精通
后端·elasticsearch
用户962377954481 天前
CTF 伪协议
php
洛森唛2 天前
Elasticsearch DSL 查询语法大全:从入门到精通
后端·elasticsearch
BingoGo3 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack3 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
Elasticsearch4 天前
如何使用 Agent Builder 排查 Kubernetes Pod 重启和 OOMKilled 事件
elasticsearch
BingoGo4 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack4 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端