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

OkHttp、Retrofit、RxJava:一文讲清楚

一、okHttp的同步和异步请求

Call 是 OkHttp 的核心接口,代表一个已准备好执行的 HTTP 请求。它支持 同步 和 异步 两种模式:

        enqueue——>okHttp异步

OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://example.com").build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onResponse(Call call, Response response) throws IOException {System.out.println("Response: " + response.body().string());}@Overridepublic void onFailure(Call call, IOException e) {System.err.println("Request failed: " + e.getMessage());}
});

        execute——>同步请求

        特点

  1. 阻塞线程
    请求发送后,当前线程会阻塞,直到服务器返回响应或超时。

  2. 直接返回结果
    通过 execute() 方法直接返回 Response 对象,无需回调。

  3. 线程管理
    不能在主线程中执行,否则会触发 NetworkOnMainThreadException 异常。同步请求必须在后台线程中执行,可以使用 ThreadExecutorService 或 RxJava 等工具管理线程。

  4. 资源释放
    Response 对象实现了 Closeable 接口,使用 try-with-resources 语法确保资源释放。

  5. 超时设置
    默认超时为 10 秒,可通过 OkHttpClient.Builder 自定义:

OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://example.com").build();
try (Response response = client.newCall(request).execute()) {if (response.isSuccessful()) {System.out.println("Response: " + response.body().string());} else {System.err.println("Request failed: " + response.code());}
} catch (IOException e) {System.err.println("Request error: " + e.getMessage());
}

    ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.execute(() -> {try (Response response = client.newCall(request).execute()) {if (response.isSuccessful()) {System.out.println
    特性同步请求(execute异步请求(enqueue
    线程阻塞阻塞当前线程,直到请求完成不阻塞线程,后台执行
    结果获取直接返回 Response 对象通过 Callback 回调处理结果
    线程管理需手动管理线程,避免主线程阻塞自动在后台线程执行,主线程无影响
    适用场景需立即获取结果的场景(如单元测试)需异步处理的场景(如网络请求)

    二、okHttp+Rxjava

    Observable<Response> observable = Observable.create(emitter -> {Call call = client.newCall(request);call.enqueue(new Callback() {@Overridepublic void onResponse(Call call, Response response) {if (!emitter.isDisposed()) {emitter.onNext(response);emitter.onComplete();}}@Overridepublic void onFailure(Call call, IOException e) {if (!emitter.isDisposed()) {emitter.onError(e);}}});emitter.setCancellable(call::cancel);
    });observable.subscribeOn(Schedulers.io()) // 在 IO 线程执行.observeOn(AndroidSchedulers.mainThread()) // 在主线程处理结果.subscribe(new Observer<Response>() {@Overridepublic void onSubscribe(Disposable d) {// 订阅时调用}@Overridepublic void onNext(Response response) {System.out.println("Response: " + response.body().string());}@Overridepublic void onError(Throwable e) {System.err.println("Error: " + e.getMessage());}@Overridepublic void onComplete() {// 请求完成时调用}});

    二、Retrofit 的同步与异步用法,用Call发起请求

    Retrofit 内部使用 OkHttp 作为 HTTP 客户端,这意味着在 Retrofit 的配置中,你可以定制 OkHttp 的各种参数(如超时设置、拦截器等)。

    为了更好地支持异步编程,Retrofit 提供了 RxJava 的 CallAdapter。通过这个适配器,你可以让 API 接口直接返回 Observable、Single 等 RxJava 类型,从而使用 RxJava 的强大操作符来处理请求结果和错误。

    public interface ApiService {@GET("users")Call<List<User>> getUsers();
    }
    Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.example.com/").addConverterFactory(GsonConverterFactory.create())  // 使用 Gson 进行 JSON 转换.build();ApiService apiService = retrofit.create(ApiService.class);
    

    Retrofit同步请求

            需在子线程中调用,否则会触发 NetworkOnMainThreadException

    new Thread(new Runnable() {@Overridepublic void run() {try {Call<List<User>> call = apiService.getUsers();Response<List<User>> response = call.execute();if (response.isSuccessful() && response.body() != null) {List<User> users = response.body();// 处理返回的数据} else {Log.e("Retrofit", "Response error: " + response.code());}} catch (IOException e) {e.printStackTrace();}}
    }).start();
    

    Retrofit异步请求

    Call<List<User>> call = apiService.getUsers();
    call.enqueue(new Callback<List<User>>() {@Overridepublic void onResponse(Call<List<User>> call, Response<List<User>> response) {if (response.isSuccessful() && response.body() != null) {List<User> users = response.body();// 处理返回的数据,比如更新 UI} else {// 请求成功,但是服务器返回错误码,比如 404、500 等Log.e("Retrofit", "Response error: " + response.code());}}@Overridepublic void onFailure(Call<List<User>> call, Throwable t) {// 请求失败,比如网络错误或解析错误Log.e("Retrofit", "Request failed", t);}
    });
    

    三、Retrofit + RxJava 的同步/异步与线程统一处理,用Observable发起请求

    Observable 是 RxJava 的响应式编程模型,用于处理异步数据流。其优势包括:

    • 链式调用:通过操作符(如 mapflatMap)简化复杂逻辑。
    • 线程调度:通过 subscribeOn 和 observeOn 控制线程切换。
    • 错误处理:通过 onErrorReturn 或 retry 实现容错。

    同步请求

    public interface ApiService {@GET("users/{id}")Observable<User> getUserRx(@Path("id") int id); // 返回 Observable
    }apiService.getUserRx(1).subscribeOn(Schedulers.io()) // 指定请求线程.observeOn(Schedulers.io())   // 指定响应处理线程.blockingSubscribe(user -> {// 同步阻塞获取结果});

    异步请求

    // 1. 定义 API 接口,使用 RxJava 的 Observable 作为返回类型
    public interface ApiService {@GET("users")Observable<List<User>> getUsers();
    }// 2. 配置 OkHttp 客户端(可添加拦截器、日志打印等)
    OkHttpClient okHttpClient = new OkHttpClient.Builder()// 例如:添加日志拦截器// .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).build();// 3. 配置 Retrofit,同时添加 Gson 转换器和 RxJava 适配器
    Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.example.com/").client(okHttpClient).addConverterFactory(GsonConverterFactory.create())          // JSON 数据解析.addCallAdapterFactory(RxJava2CallAdapterFactory.create())      // RxJava 适配器.build();// 4. 创建 API 服务实例
    ApiService apiService = retrofit.create(ApiService.class);// 5. 使用 RxJava 进行网络请求
    apiService.getUsers().subscribeOn(Schedulers.io())                   // 在 IO 线程执行网络请求.observeOn(AndroidSchedulers.mainThread())      // 在主线程处理返回结果.subscribe(users -> {// 成功回调,处理用户数据}, throwable -> {// 错误回调,处理异常情况});
    

    方案线程管理代码复杂度适用场景
    OkHttp 原生手动切换简单请求、低耦合场景
    Retrofit 原生手动切换接口化请求、中等复杂度
    Retrofit+RxJava自动统一管理复杂异步流、高可维护性

    四、具体使用Retrofit+RxJava

    // 1. 定义服务接口
    public interface UserService {@POST("/user/{userId}/profile")Observable<BaseResponse<UserProfile>> updateProfile(@Path("userId") String userId,@Body ProfileParams params);
    }// 2. 发起请求
    NetworkApi.createService(UserService.class, ServiceType.User.name()).updateProfile("123", new ProfileParams("Kimi", "avatar.jpg")).compose(NetworkApi.applySchedulers()).subscribe(new BaseObserver<UserProfile>() {@Overridepublic void onSuccess(UserProfile profile) {// 更新UI}@Overridepublic void onBusinessError(int code, String msg) {// 显示错误提示}});

    设计优势

    • 责任链模式:每个方法专注单一职责(创建→配置→调度→响应)
    • 类型安全:通过泛型确保数据模型一致性
    • 异常隔离:BaseObserver集中处理网络/业务异常
    • 线程透明:applySchedulers()隐藏线程切换细节

    该模式常见于需要支持多环境、多服务类型的现代移动应用架构,特别适合企业级应用开发中需要统一管理API请求的场景。

    这是典型的Retrofit+RxJava组合的网络请求链式调用写法,结合了工厂模式、建造者模式和响应式编程思想。其核心结构可分为四个关键部分:

    1.服务实例创建
    NetworkApi.createService(ApiService.class, ServiceType.License.name())
    • NetworkApi是自定义的工厂类,封装了Retrofit实例的创建过程
    • createService()方法通过动态代理生成ApiService接口的实现类
    • ServiceType.License.name()指定服务类型,通常用于动态配置baseUrl(如区分认证服务、业务服务等)
    2.具体API操作
    .action(id, params)
    • action()对应ApiService接口中定义的端点方法:
    @POST("/api/{serviceType}/actions")
    Observable<BaseResponse<T>> action(@Path("serviceType") String serviceType,@Body ActionParams params
    );
    • id参数可能用于路径替换(@Path注解),params作为请求体(@Body注解)
    3.线程调度组合
    .compose(NetworkApi.applySchedulers(...))
    • compose()是RxJava的操作符,统一应用线程切换规则
    • applySchedulers()典型实现:
    4.观察者封装
    new BaseObserver<BaseResponse<AccessConsentRecordDetailBean>>()
    • 自定义的BaseObserver处理通用逻辑:
    public abstract class BaseObserver<T> implements Observer<T> {@Overridepublic void onError(Throwable e) {// 统一错误处理(网络异常、业务异常等)}@Overridepublic void onNext(T response) {if (response.isSuccess()) {onSuccess(response.getData());} else {onBusinessError(response.getCode(), response.getMessage());}}
    }

    五、Flowable与Observable

    FlowableObservable是RxJava中两种核心的响应式数据流类型,结合Retrofit使用时需要根据具体场景进行选型。以下是两者的核心区别及在Retrofit中的实践建议:

    类型特性Retrofit集成场景
    Observable无背压机制的异步数据流,支持同步/异步操作,适合轻量级请求简单API调用(如获取用户信息、配置数据)
    Flowable支持背压控制的响应式流,内置5种策略处理生产消费速度差异大文件传输、实时数据推送等高并发场景

    核心区别

    1. 背压处理机制
    • Flowable
      通过BackpressureStrategy配置策略(ERROR/BUFFER/DROP/LATEST/MISSING),在Retrofit中处理大数据流时需显式指定策略:
    @GET("api/sensor-data")
    Flowable<Data> getSensorData(@Query("deviceId") String id);  // 默认使用ERROR策略[5](@ref)
    • Observable
      无背压控制,Retrofit接口直接返回Observable时需确保数据量可控,否则可能引发OOM
    2. 线程模型

    Flowable
    强制异步订阅,Retrofit需配合subscribeOn(Schedulers.io())使用:

    api.getSensorData("DEV001").subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())

    Observable
    支持同步调用,适合快速响应的本地缓存查询:

    @GET("api/profile")
    Observable<User> getUserProfile();  // 同步获取用户数据[9](@ref)
    3. 性能表现
    • Flowable
      因背压检测机制,吞吐量比Observable低约15-30%,但内存更安全
    • Observable
      无额外性能损耗,适合高频低数据量请求(如按钮点击事件统计)
    4.集成实现
    • BUFFER:文件下载(需注意内存监控)
    Flowable.create(emitter -> {...}, BackpressureStrategy.BUFFER)
    • DROP:实时股票行情推送(丢弃过时数据)
    • LATEST:即时聊天消息(保留最新消息)
    5.错误处理对比
    • Observable需手动捕获异常:
    .subscribe(data -> {...},error -> { // 需处理所有异常 }
    )
    • Flowable通过onBackpressureXXX操作符自动处理:
    .onBackpressureDrop(dropped -> log("丢弃数据:" + dropped))

    性能优化建议

    1. 混合使用策略
      对核心业务接口使用Flowable+BUFFER策略,非核心功能使用Observable

    2. 动态缓存控制
      通过rx2.buffer-size参数调整Flowable缓存池:

      System.setProperty("rx2.buffer-size", "256");  // 默认128[7](@ref)
    3. 生命周期管理
      使用CompositeDisposable统一释放资源:

      CompositeDisposable disposables = new CompositeDisposable();disposables.add(api.getDataStream().subscribe(data -> {...}));

    通过合理选择Flowable与Observable,可使Retrofit网络层在保证稳定性的同时获得最佳性能。可以在金融交易、物联网等高频场景优先采用Flowable,而在常规业务API中使用Observable以降低复杂度。

    相关文章:

    OkHttp、Retrofit、RxJava:一文讲清楚

    一、okHttp的同步和异步请求 Call 是 OkHttp 的核心接口&#xff0c;代表一个已准备好执行的 HTTP 请求。它支持 同步 和 异步 两种模式&#xff1a; enqueue——>okHttp异步 OkHttpClient client new OkHttpClient();Request request new Request.Builder().url("…...

    星环科技推出DeepSeek全场景解决方案:即开即用、企业级部署、端侧智能三位一体

    星环科技&#xff08;688031.SH&#xff09;正式发布DeepSeek全场景解决方案&#xff0c;全面覆盖个人用户、企业客户及行业场景需求&#xff0c;为用户提供从个人到企业、从云端到本地的全方位AI应用支持&#xff0c;为不同需求的用户提供了灵活、高效且安全的AI解决方案。 省…...

    Redis缓存一致性难题:如何让数据库和缓存不“打架”?

    标题&#xff1a;Redis缓存一致性难题&#xff1a;如何让数据库和缓存不“打架”&#xff1f;&#xff08;附程序员脱发指南&#xff09; 导言&#xff1a;当数据库和缓存成了“异地恋” 想象一下&#xff1a;你刚在美团下单了一份麻辣小龙虾&#xff0c;付款后刷新页面&#…...

    动态部署Web应用程序与web.xml配置详解

    文章目录 前言一、动态部署Web应用程序1.1 什么是动态部署&#xff1f;1.2 动态部署的步骤1.3 动态部署的优势 二、web.xml 配置文件2.1 什么是web.xml&#xff1f;2.2 web.xml 文件的结构2.2.1常见配置&#xff08;1&#xff09; 配置上下文参数(2) 配置Servlet(3)配置过滤器(…...

    2025年软考报名费用是多少?全国费用汇总!

    软考报名时间终于确定了&#xff01;想要参加2025年软考的同学们注意啦&#xff01;特别是那些一年只有一次考试机会的科目&#xff0c;千万不要错过哦&#xff01;这里为大家整理了各地的报名时间、科目、费用等信息&#xff0c;快来看看吧&#xff01; 一、2025年软考时间安…...

    DeepSeek 15天指导手册——从入门到精通 PDF(附下载)

    DeepSeek使用教程系列--DeepSeek 15天指导手册——从入门到精通pdf下载&#xff1a; https://pan.baidu.com/s/1PrIo0Xo0h5s6Plcc_smS8w?pwd1234 提取码: 1234 或 https://pan.quark.cn/s/2e8de75027d3 《DeepSeek 15天指导手册——从入门到精通》以系统化学习路径为核心&…...

    【Javascript】js精度丢失

    当JS处理大整数或者浮点数的时候会出现精度丢失的情况。 Javascript的数字都使用双精度浮点数表示&#xff0c;遵循IEEE754标准 比如我遇到的问题&#xff0c;对一个小数的四舍五入&#xff0c;保留2位小数&#xff1a; 235.985≈235.98 235.9851≈235.99 原理请大家参考百度&…...

    让Word插上AI的翅膀:如何把DeepSeek装进Word

    在日常办公中&#xff0c;微软的Word无疑是我们最常用的文字处理工具。无论是撰写报告、编辑文档&#xff0c;还是整理笔记&#xff0c;Word都能胜任。然而&#xff0c;随着AI技术的飞速发展&#xff0c;尤其是DeepSeek的出现&#xff0c;我们的文字编辑方式正在发生革命性的变…...

    秒杀系统的常用架构是什么?怎么设计?

    架构 秒杀系统需要单独部署&#xff0c;如果说放在订单服务里面&#xff0c;秒杀的系统压力太大了就会影响正常的用户下单。 常用架构&#xff1a; Redis 数据倾斜问题 第一步扣减库存时 假设现在有 10 个商品需要秒杀&#xff0c;正常情况下&#xff0c;这 10 个商品应该均…...

    【文件基础操作】小笔记

    Step1: 现在项目文件夹&#xff08;我的项目叫做RunPony&#xff09;下创建一个a.txt文本文件&#xff0c;手动写入一些数字&#xff0c;保存 Step2: 现在在main.c内写一个基本的文件处理的程序 Step3: 现在已经知道如何打开关闭文件&#xff0c;下一步要搞懂如何读取txt内的…...

    RabbitMQ系列(七)基本概念之Channel

    RabbitMQ 中的 Channel&#xff08;信道&#xff09; 是客户端与 RabbitMQ 服务器通信的虚拟会话通道&#xff0c;其核心作用在于优化资源利用并提升消息处理效率。以下是其核心机制与功能的详细解析&#xff1a; 一、Channel 的核心定义 虚拟通信链路 Channel 是建立在 TCP 连…...

    本地搭建Koodo Reader书库结合内网穿透打造属于自己的移动图书馆

    文章目录 前言1. Koodo Reader 功能特点1.1 开源免费1.2 支持众多格式1.3 多平台兼容1.4 多端数据备份同步1.5 多功能阅读体验1.6 界面简洁直观 2. Koodo Reader安装流程2.1 安装Git2.2 安装Node.js2.3 下载koodo reader 3. 安装Cpolar内网穿透3.1 配置公网地址3.2 配置固定公网…...

    DeepSeek R1 训练策略4个阶段解析

    DeepSeek R1 训练策略解析 DeepSeek R1 训练策略解析1. 冷启动监督微调&#xff08;Cold Start SFT&#xff09;**该阶段的主要目标**&#xff1a; 2. 面向推理的强化学习&#xff08;RL for Reasoning&#xff09;**该阶段的主要目标**&#xff1a; 3. 拒绝采样和监督微调&…...

    【博资考4】网安学院-硕转博考试内容

    【博资考4】硕转博考试内容 - 网络安全与基础理论 写在最前面一. **21年硕转博面试内容回顾**网络、逆向、操作系统、攻防、漏洞1. **网络安全常见攻击方式及其防范措施**1.1 **DDoS攻击&#xff08;分布式拒绝服务&#xff09;**1.2 **SQL注入攻击**1.3 **XSS攻击&#xff08;…...

    30 分钟从零开始入门 CSS

    HTML CSS JS 30分钟从零开始入门拿下 HTML_html教程-CSDN博客 30 分钟从零开始入门 CSS-CSDN博客 JavaScript 指南&#xff1a;从入门到实战开发-CSDN博客 前言 最近也是在复习&#xff0c;把之前没写的博客补起来&#xff0c;之前给大家介绍了 html&#xff0c;现在是 CSS 咯…...

    C语言综合案例:学生成绩管理系统

    C语言综合案例&#xff1a;学生成绩管理系统 需求 1.存储最多50名学生的信息&#xff08;不使用结构体&#xff09; 2.每个学生包含&#xff1a; 学号&#xff08;字符数组&#xff09;姓名&#xff08;字符数组&#xff09;3门课程成绩&#xff08;一维数组&#xff09; …...

    使用python做http代理请求

    有这样一个需求现在有两台A&#xff0c;B两台电脑组成了一个局域网&#xff0c;在A电脑上开发webjava应用&#xff0c;需要调用第三方接口做http请求&#xff0c;但是这个请求只能在B电脑上请求。 一种解决方案&#xff1a;自定义一个中间服务&#xff0c;在电脑B上运行一个简…...

    数据库事务的基本要素(ACID)

    数据库事务的基本要素&#xff08;ACID&#xff09; 在数据库管理系统&#xff08;DBMS&#xff09;中&#xff0c;事务&#xff08;Transaction&#xff09;是一个或多个数据库操作的集合&#xff0c;这些操作要么全部成功&#xff0c;要么全部失败。事务的目标是保证数据的一…...

    DeepSeek R1满血+火山引擎详细教程

    DeepSeek R1满血火山引擎详细教程 一、安装Cherry Studio。 Cherry Studio AI 是一款强大的多模型 AI 助手,支持 iOS、macOS 和 Windows 平台。可以快速切换多个先进的 LLM 模型,提升工作学习效率。下载地址 https://cherry-ai.com/ 认准官网&#xff0c;无强制注册。 这…...

    大型语言模型技术对比:阿里Qwen qwq、DeepSeek R1、OpenAI o3与Grok 3

    1. 引言 在人工智能&#xff08;AI&#xff09;领域中&#xff0c;大型语言模型&#xff08;Large Language Models&#xff0c;简称LLM&#xff09;近年来取得了显著的突破。从早期的GPT-3到如今的各种高级模型&#xff0c;这些技术不仅推动了自然语言处理&#xff08;NLP&am…...

    Linux应用开发之网络套接字编程(实例篇)

    服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

    rknn优化教程(二)

    文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

    智能在线客服平台:数字化时代企业连接用户的 AI 中枢

    随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

    HTML前端开发:JavaScript 常用事件详解

    作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

    现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

    现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

    并发编程 - go版

    1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

    webpack面试题

    面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...

    DeepSeek越强,Kimi越慌?

    被DeepSeek吊打的Kimi&#xff0c;还有多少人在用&#xff1f; 去年&#xff0c;月之暗面创始人杨植麟别提有多风光了。90后清华学霸&#xff0c;国产大模型六小虎之一&#xff0c;手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水&#xff0c;单月光是投流就花费2个亿。 疯…...

    FTXUI::Dom 模块

    DOM 模块定义了分层的 FTXUI::Element 树&#xff0c;可用于构建复杂的终端界面&#xff0c;支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...

    Docker环境下安装 Elasticsearch + IK 分词器 + Pinyin插件 + Kibana(适配7.10.1)

    做RAG自己打算使用esmilvus自己开发一个&#xff0c;安装时好像网上没有比较新的安装方法&#xff0c;然后找了个旧的方法对应试试&#xff1a; &#x1f680; 本文将手把手教你在 Docker 环境中部署 Elasticsearch 7.10.1 IK分词器 拼音插件 Kibana&#xff0c;适配中文搜索…...