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

RPC学习

一、什么是 RPC

RPC(Remote Procedure Call),即远程过程调用,是一种计算机通信协议,它允许运行在一台计算机上的程序调用另一台计算机上的子程序或函数,就好像调用本地程序中的函数一样,无需程序员显式地去编写处理网络通信、数据序列化与反序列化等底层细节的代码。

简单来说,就是让不同机器上的程序之间能够方便地进行通信和交互,使得分布式系统的开发更加便捷高效。

二、为什么要用 RPC

  1. 分布式系统需求
    在现代的大型应用系统中,往往采用分布式架构,将不同的功能模块部署在不同的服务器上。例如,电商系统中订单处理、库存管理、用户认证等模块可能分别位于不同的机器。RPC 可以方便地实现这些不同模块之间的通信,让它们协同工作,就如同在一个单机系统中一样。

  2. 提高系统可扩展性
    当业务增长需要增加新的功能模块或者对现有模块进行扩展时,通过 RPC 可以轻松地将新模块添加到分布式系统中,并与其他模块进行交互,而不需要对整个系统进行大规模的重构。

  3. 资源共享与复用
    不同的应用程序或服务可能需要使用相同的功能,比如多个业务系统都需要进行数据加密、文件上传下载等功能。通过将这些公共功能封装成 RPC 服务并发布出去,其他应用可以方便地调用,实现资源的共享与复用。

  4. 跨语言协作
    在一个复杂的企业级应用环境中,不同的团队可能使用不同的编程语言来开发各自的模块。RPC 支持多种语言实现,使得不同语言编写的程序之间能够进行通信,例如用 Java 编写的服务可以被 Python 编写的客户端调用,促进了跨语言的协作。

三、常用的 RPC 框架

  1. gRPC

    • 由 Google 开发并开源,基于 HTTP/2 协议进行通信,性能较高。
    • 使用 Protocol Buffers 作为默认的接口定义语言和消息序列化格式,具有高效的序列化和反序列化能力。
    • 支持多种编程语言,如 Java、Python、C++、Go 等,方便在不同语言环境下开发分布式应用。
  2. Dubbo

    • 阿里巴巴开源的一款高性能、轻量级的 RPC 框架,在 Java 领域应用广泛。
    • 提供了丰富的服务治理功能,如服务注册与发现、负载均衡、容错处理等,能够很好地应对大规模分布式系统中的复杂情况。
    • 可以与 Spring 框架无缝集成,方便 Java 开发者使用。
  3. Thrift

    • 最初由 Facebook 开发,现在是 Apache 的开源项目。
    • 支持多种通信协议(如 TCP、UDP 等)和多种序列化方式(如二进制、JSON 等),具有较高的灵活性。
    • 同样支持多种编程语言,可用于构建跨语言的分布式应用。

四、RPC 原理

  1. 客户端调用过程

    • 当客户端程序需要调用远程服务时,首先会通过本地的代理(Stub)对象来发起调用。这个代理对象就像是远程服务在本地的一个替身,它隐藏了远程调用的底层细节。
    • 客户端将调用的参数进行序列化,即将参数对象转换为可以在网络上传输的格式,比如将 Java 对象序列化为字节流。
    • 然后通过网络将序列化后的参数发送给远程服务所在的服务器。
  2. 服务器端处理过程

    • 服务器端有一个对应的骨架(Skeleton)对象,它接收从客户端发送过来的序列化后的参数。
    • 首先对接收的参数进行反序列化,将其还原为服务器端能够处理的对象格式。
    • 然后根据调用的方法名等信息,找到对应的实际服务实现类,并执行相应的方法。
    • 执行完方法后,将返回结果进行序列化,再通过网络发送回客户端。
  3. 客户端接收结果

    • 客户端接收到服务器端返回的序列化后的结果后,进行反序列化操作,将其还原为本地能够处理的结果对象格式,最后将结果返回给调用的客户端程序部分,完成整个远程调用过程。

五、如何做到透明化远程服务调用

  1. 代理机制
    通过在客户端创建代理对象(Stub),让客户端程序感觉就像是在调用本地的函数一样。代理对象负责处理与远程服务通信的所有细节,包括参数序列化、网络发送、接收结果、反序列化等,对客户端程序隐藏了这些复杂的远程调用过程。

  2. 接口定义一致性
    在客户端和服务器端定义相同的服务接口,确保双方对于服务的方法名、参数类型、返回值类型等有一致的理解。这样客户端按照接口定义进行调用,服务器端按照接口定义进行实现和处理,使得远程调用过程在逻辑上更加清晰和一致,仿佛是在本地进行的调用。

  3. 服务注册与发现机制
    采用服务注册与发现系统,如 Zookeeper、Consul 等。服务器端将自己提供的服务注册到注册中心,客户端通过查询注册中心来获取需要调用的服务的地址等信息。这样,客户端不需要事先知道远程服务的确切位置,只要知道服务的名称等标识信息,就可以通过注册中心找到并调用相应的服务,进一步增强了远程服务调用的透明性。

六、如何对消息进行编码和解码

  1. 编码(序列化)

    • 选择合适的序列化方式:根据应用场景和需求选择合适的序列化协议,如 JSON、Protocol Buffers、XML 等。不同的序列化方式有不同的特点,例如 JSON 格式简单易懂,适合于与 Web 应用交互;Protocol Buffers 则具有高效的序列化和反序列化性能,适合于对性能要求较高的场景。
    • 按照序列化协议规则进行操作:一旦确定了序列化协议,就需要按照该协议的具体规则来对消息对象进行操作。比如,对于 JSON 序列化,需要将对象的属性转换为 JSON 格式的键值对;对于 Protocol Buffers,需要先定义好消息结构的.proto 文件,然后根据文件中的定义将对象进行序列化。
  2. 解码(反序列化)

    • 识别序列化格式:首先要确定接收到的消息是采用哪种序列化格式进行编码的,这通常可以通过消息头或者约定的标识来判断。
    • 按照对应序列化协议规则进行反操作:根据确定的序列化格式,按照其反序列化的规则将接收到的消息还原为原始的对象格式。例如,对于 JSON 序列化的消息,需要将 JSON 格式的键值对转换为对象的属性;对于 Protocol Buffers,需要根据.proto 文件中的定义将接收到的字节流反序列化 为对象。

七、如何发布自己的服务

  1. 定义服务接口
    首先要明确自己要发布的服务提供哪些功能,然后使用合适的接口定义语言(如 Java 中的接口、Protocol Buffers 中的.proto 文件等)来定义服务的接口,包括服务的方法名、参数类型、返回值类型等信息。

  2. 实现服务接口
    根据定义好的服务接口,在服务器端编写具体的服务实现类,实现接口中定义的各个方法,这些方法将包含具体的业务逻辑来处理客户端的调用请求。

  3. 选择 RPC 框架
    根据项目的需求和特点,选择合适的 RPC 框架,如前面提到的 gRPC、Dubbo、Thrift 等。不同的框架有不同的特点和优势,需要综合考虑性能、功能、支持的编程语言等因素。

  4. 配置服务信息
    在选定的 RPC 框架中,按照框架的要求配置服务的相关信息,如服务的名称、端口号、服务所在的主机地址等,以便于其他客户端能够找到并调用该服务。

  5. 注册服务
    将服务注册到服务注册与发现系统(如 Zookeeper、Consul 等)中,这样客户端就可以通过查询注册中心来获取服务的相关信息,从而实现对服务的调用。在注册过程中,需要提供服务的名称、地址、端口号等关键信息。

  6. 启动服务
    完成上述步骤后,启动服务,使其处于可被客户端调用的状态。服务启动后,就可以等待客户端的调用请求,并按照服务实现类中的业务逻辑进行处理,将处理结果返回给客户端。

相关文章:

RPC学习

一、什么是 RPC RPC(Remote Procedure Call),即远程过程调用,是一种计算机通信协议,它允许运行在一台计算机上的程序调用另一台计算机上的子程序或函数,就好像调用本地程序中的函数一样,无需程序…...

STM32端口模拟编码器输入

文章目录 前言一、正交编码器是什么?二、使用步骤2.1开启时钟2.2配置编码器引脚 TIM3 CH1(PA6) CH2 (PA7)上拉输入2.3.初始化编码器时基2.4 初始化编码器输入2.5 配置编码器接口2.6 开启定时器2.7获取编码器数据 三、参考程序四、测试结果4.1测试方法4.2串口输出结果…...

深入理解 MyBatis 的缓存机制:一级缓存与二级缓存

MyBatis 是目前 Java 开发中常用的一种 ORM(对象关系映射)框架,它不仅简化了 SQL 语句的编写和管理,还提供了强大的缓存机制,用以提高数据库访问的性能。MyBatis 的缓存分为一级缓存和二级缓存,分别应用于不…...

做一个FabricJS.cc的中文文档网站——面向markdown编程

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,用爱发电&#…...

Elasticsearch在部署时,对Linux的设置有哪些优化方法?

大家好,我是锋哥。今天分享关于【Elasticsearch在部署时,对Linux的设置有哪些优化方法?】面试题。希望对大家有帮助; Elasticsearch在部署时,对Linux的设置有哪些优化方法? 1000道 互联网大厂Java工程师 精…...

ThingsBoard规则链节点:Azure IoT Hub 节点详解

目录 引言 1. Azure IoT Hub 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 数据传输 3.2 数据分析 3.3 设备管理 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台,提供了设备…...

SpringBoot线程池的使用

SpringBoot线程池的使用 在现代Web应用开发中,特别是在使用Spring Boot框架时,合理使用线程池可以显著提高应用的性能和响应速度。线程池不仅能够减少线程创建和销毁的开销,还能有效地控制并发任务的数量,避免因线程过多而导致的…...

ubuntu中使用ffmpeg和nginx推流rtmp视频

最近在测试ffmpeg推流rtmp视频,单独安装ffmpeg是无法完成推流的,需要一个流媒体服务器,常用nginx,可以直接在ubuntu虚拟机里面测试一下。 测试过程不涉及编译ffmpeg和nginx,仅使用基本功能: 1 安装ffmpeg …...

如何在CodeIgniter中添加或加载模型

在CodeIgniter框架中,模型(Model)是用于与数据库进行交互的重要组件。模型通常包含数据库查询、业务逻辑以及与数据库表相关的函数。以下是如何在CodeIgniter中添加或加载模型的步骤: 1. 创建模型文件 首先,你需要在…...

加菲工具 - 好用免费的在线工具集合

加菲工具 https://orcc.online AI 工具 加菲工具 集合了目前主流的,免费可用的ai工具 文档处理 加菲工具 pdf转word、office与pdf互转等等工具都有链接 图片图标 加菲工具 统计了好用免费的在线工具 编码解码 加菲工具 base64编码解码、url编码解码、md5计算…...

Centos 8, add repo

Centos repo前言 Centos 8更换在线阿里云创建一键更换repo 自动化脚本 华为Centos 源 , 阿里云Centos 源 华为epel 源 , 阿里云epel 源vim /centos8_repo.sh #!/bin/bash # -*- coding: utf-8 -*- # Author: make.han...

神经网络12-Time-Series Transformer (TST)模型

Time-Series Transformer (TST) 是一种基于 Transformer 架构的深度学习模型,专门用于时序数据的建模和预测。TST 是 Transformer 模型的一个变种,针对传统时序模型(如 RNN、LSTM)在处理长时间依赖、复杂数据关系时的限制而提出的…...

在 Ubuntu 上安装 Yarn 环境

在 Ubuntu 上安装 Yarn 环境 步骤 1: 更新系统步骤 2: 安装 Node.js步骤 3: 安装 Yarn方法 1: 使用 npm 安装方法 2: 使用 APT 安装 步骤 4: 验证安装总结 在 Ubuntu 上安装 Yarn 环境可以通过以下步骤完成: 步骤 1: 更新系统 首先,确保你的系统是最新…...

OEM sql monitoring 类似SQL

不够OEM 全面 select a.inst_id,a.time_since_last_wait_micro,a.last_call_et,a.sql_id,a.sql_hash_value, a.username,a.pdml_enabled,a.pdml_status ,a.prev_sql_id from gv$session a where a.statusACTIVE and a.sql_id is not null and a.username is not null select …...

【数据分析】基于GEE实现大津算法提取洞庭湖流域水体

大津算法提取水体 1.写在前面2.洞庭湖水体识别1.写在前面 最大类间方差法,也称为Otsu或大津法,是一种高效的图像二值化算法,由日本学者Otsu于1979年提出。该算法基于图像的频率分布直方图,假设图像包含两类像素(前景和背景),并计算出一个最佳阈值,以最大化类间方差,从…...

MySQL中的ROW_NUMBER窗口函数简单了解下

ROW_NUMBER() 是 MySQL8引入的窗口函数之一,它为查询结果集中的每一行分配一个唯一的顺序号(行号)。这个顺序号是基于窗口函数的 ORDER BY 子句进行排序的,可以根据指定的排序顺序生成连续的整数值。 ROW_NUMBER() 在分页、去重、…...

pyhton django web集群基于linux定时任务

基于django management/commands目录下的脚本 from django.core.management import BaseCommand import logging import uuid from pia.utils.cache import reset_redis_expire from pia.utils.reids_key import TASK_KEYlogging logging.getLogger(task)""" …...

STM32串口——5个串口的使用方法

参考文档 STM32串口——5个串口的使用方法_51CTO博客_stm32串口通信的接收与发送 串口是我们常用的一个数据传输接口,STM32F103系列单片机共有5个串口,其中1-3是通用同步/异步串行接口USART(Universal Synchronous/Asynchronous Receiver/Transmitter)…...

友思特新闻 | 友思特荣获广州科技创新创业大赛智能装备行业赛初创组优胜企业!

2024年11月19日,第十三届中国创新创业大赛(广东广州赛区)暨2024年广州科技创新创业大赛智能装备行业赛颁奖典礼隆重举行。 赛事奖项介绍:广州科技创新创业大赛智能装备行业赛 第十三届“中国创新创业大赛(广东广州赛区…...

react函数式组件中的路由传参方式

React Router 提供了多种方式来传递路由参数: URL 路径参数:通过动态路由和 useParams 获取。查询参数:通过 useLocation 获取 URL 查询字符串。路由状态传递:通过 state 属性在导航时传递数据,不在 URL 中显示&#…...

docker部署微信机器人实现任意群聊发送消息

前言:底层技术用的是wechaty,我只是做了一些集成。 此项目源码如下:https://gitee.com/yang123888/wechaty-wxtest 拉取: docker pull registry.cn-hangzhou.aliyuncs.com/yamyang/kercore-wx-bot:1.0.0运行: dock…...

Vercel 设置自动部署 GitHub 项目

Vercel 设置自动部署 GitHub 项目 问题背景 最近 Vercel 调整了其部署政策,免费版用户无法继续使用自动部署功能,除非升级到 Pro 计划。但是,我们可以通过配置 Deploy Hooks 来实现同样的自动部署效果。 解决方案 通过设置 Vercel 的 Dep…...

【shodan】(七)命令

shodan基础(七) 声明:该笔记为up主 泷羽的课程笔记,本节链接指路。 警告:本教程仅作学习用途,若有用于非法行为的,概不负责。 查询账号 查看账户扫描次数 shodan info查询域名信息 shodan d…...

文件上传代码分析

目录 不同类型的语言脚本语⾔/解释型语⾔⼀次编译到处运⾏编译型语⾔ 不同语⾔的webshell上传差异脚本语⾔/解释型语⾔⼀次编译到处运⾏编译型语⾔ ⽂件上传到webshell任意⽂件上传js检测解析规则MIME⽂件头后缀检测失效 NTFS Tricks 不同类型的语言 脚本语⾔/解释型语⾔ 代表…...

深入解析分布式遗传算法及其Python实现

目录 深入解析分布式遗传算法及其Python实现目录第一部分:分布式遗传算法的背景与原理1.1 遗传算法概述1.2 分布式遗传算法的引入1.3 分布式遗传算法的优点与挑战优点:挑战:第二部分:分布式遗传算法的通用Python实现2.1 基本组件的实现第三部分:案例1 - 基于多种交叉与变异…...

World of Warcraft /script SetRaidTarget(“target“, n, ““) n=8,7,6,5,4,3,2,1,0

魔兽世界执行当前目标标记方法 /script SetRaidTarget("target", n, "") n8,7,6,5,4,3,2,1,0 解析这个lua脚本 D:\Battle.net\World of Warcraft\_classic_\Interface\AddOns\wMarker wMarker.lua /script SetRaidTarget("target", 8, &quo…...

django authentication 登录注册

文章目录 前言一、django配置二、后端实现1.新建app2.编写view3.配置路由 三、前端编写1、index.html2、register.html3、 login.html 总结 前言 之前,写了django制作简易登录系统,这次利用django内置的authentication功能实现注册、登录 提示&#xff…...

阿里云整理(一)

阿里云整理 1. 介绍规模 2. 专业名词2.1 专有网络VPC2.2 安全组SG2.3 云服务器ECS2.4 资源组2.5 部署集2.5 web测试 1. 介绍 ‌阿里云是一家提供云计算和人工智能服务的科技公司,成立于2009年,总部位于杭州。‌它为全球客户提供全方位的云服务&#xff…...

鸿蒙NEXT开发案例:文字转拼音

【引言】 在鸿蒙NEXT开发中,文字转拼音是一个常见的需求,本文将介绍如何利用鸿蒙系统和pinyin-pro库实现文字转拼音的功能。 【环境准备】 • 操作系统:Windows 10 • 开发工具:DevEco Studio NEXT Beta1 Build Version: 5.0.…...

Redis高级

目录 Redis事务 语法错误 执行错误 Redis持久化 RDB持久化 RDB原理 小结 AOF持久化 AOF原理 AOF配置 AOF文件重写 RDB与AOF对比 Redis主从复制架构 搭建主从复制架构 在redis目录创建三个目录 把原来的redis.conf配置分件分贝复制一件到这三个目录中 修改配置文件…...

八股文-基础知识-面试题汇总(一)

面向对象和面向过程的区别? 面向对象和面向过程是两种不同的编程范式,它们在设计和实现软件时有着不同的理念和方法。面向对象更适合大型、复杂的项目,尤其是需要维护和扩展的系统;而面向过程更适合小型、线性的任务或对性能要求…...

玩转合宙Luat教程 基础篇④——程序基础(库、线程、定时器和订阅/发布)

文章目录 一、前言二、库三、线程四、定时器五、订阅/发布5.1 回调函数5.2 堵塞等待一、前言 教程目录大纲请查阅:玩转合宙Luat教程——导读 写一写Lua程序基础的东西。 包括如何调用库,如何创建线程、如何创建定时器,如何使用订阅/发布事件。 二、库 程序从main.lua开始通…...

openssl颁发包含主题替代名的证书–SAN

原文地址:openssl颁发包含主题替代名的证书–SAN – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 在 X.509 证书中,commonName(CN)字段只能有一个值。如果让证书支持多个域名和IP地址,…...

Unity 2020、2021、2022、2023、6000下载安装

Unity 2020、2021、2022、2023、6000 下载安装 以Unity 6000.0.24fc1下载安装为例: 打开 https://unity.cn/ 优三缔 官方网站; 点击【产品列表】→点击【查看更多】→选择自己需要的版本→点【开始使用】 点击【从Unity Hub下载】 以Windows为例&am…...

Zustand:一个轻量级的React状态管理库

文章目录 前言一、安装Zustand二、使用Zustand三、实际案例结语 前言 在现代Web开发中,状态管理是一个常见的需求,特别是在构建大型或复杂的单页面应用程序(SPA)时。React等框架虽然提供了基本的状态管理功能,但对于复…...

信创改造 - TongRDS 替换 Redis

记得开放 6379 端口哦 1)首先在服务器上安装好 TongRDS 2)替换 redis 的 host,post,passwd 3)TongRDS 兼容 jedis # 例如:更改原先 redis 中对应的 host,post,passwd 改成 TongRDS…...

Css—实现3D导航栏

一、背景 最近在其他的网页中看到了一个很有趣的3d效果,这个效果就是使用css3中的3D转换实现的,所以今天的内容就是3D的导航栏效果。那么话不多说,直接开始主要内容的讲解。 二、效果展示 三、思路解析 1、首先我们需要将这个导航使用一个大…...

Unity清除所有的PlayerPrefs

方法1: 直接在你的代码中加入这句 PlayerPrefs.DeleteAll(); 方法2: 点击编辑窗口的这里...

[蓝桥杯 2021 省 AB2] 小平方

题目描述 小蓝发现,对于一个正整数 nn 和一个小于 nn 的正整数 vv,将 vv 平方后对 nn 取余可能小于 nn 的一半,也可能大于等于 nn 的一半。 请问,在 11 到 n−1n−1 中, 有多少个数平方后除以 nn 的余数小于 nn 的一半。 例如&…...

三种蓝牙架构实现方案

一、蓝牙架构方案 1、hostcontroller双芯片标准架构 手机里面包含很多SoC或者模块,每颗SoC或者模块都有自己独有的功能,比如手机应用跑在AP芯片上,显示屏,3G/4G通信,WiFi/蓝牙等都有自己专门的SoC或者模块&#xff0…...

MacOS系统上Jmeter 录制脚本遇到的证书坑位

一、JMeter介绍与安装 1,下载及安装 jmeter官网地址 二、录制百度链接https请求时,需要导入jmeter相关证书到macos系统的更目录中. 导入方式,直接拖入mac的系统中,始终新人就可以; 三、jmeter 创建相关的录制组件…...

【Linux学习】【Ubuntu入门】2-3 make工具和makefile引入

1.使用命令新建三个.c文件vi main.c,vi input.c,vi caclcu.c,两个.h文件vi input.h,vi caclcu.h 2.vi Makefile:新建Makefile文件,输入一下内容 注意:命令列表中每条命令前用TAB键,不…...

conda下载与pip下载的区别

一、conda下载与pip下载的区别 最重要是依赖关系: pip安装包时,尽管也对当前包的依赖做检查,但是并不保证当前环境的所有包的所有依赖关系都同时满足。 当某个环境所安装的包越来越多,产生冲突的可能性就越来越大。conda会检查当…...

ubity3D基础

Unity是一个流行的游戏开发引擎,它使用C#作为其主要的编程语言。以下是一些Unity中C#编程的基础概念: • Unity编辑器: • Unity编辑器是Unity游戏引擎的核心,提供了一个可视化界面,用于创建和管理游戏项目。 • C#脚本…...

408数据结构:栈、队列和数组选择题做题笔记

408数据结构 第一章 绪论 第二章 线性表 绪论、线性表选择题做题笔记 第三章 栈、队列和数组 栈、队列和数组选择题做题笔记 文章目录 408数据结构前言 一、队列二、栈和队列的应用总结 前言 本篇文章为针对王道25数据结构课后习题的栈、队列和数组的做题笔记,后续…...

如何在 Eclipse 中调试ABAP程序

原文链接:Debugging an ABAP Program ADT 中的调试器是一个重要的诊断工具,可用于分析 ABAP 应用程序。 使用调试器,您可以通过在运行时 Debug 单步执行(F5)程序来确定程序无法正常工作的原因。这使您可以看到正在执…...

React(五)——useContecxt/Reducer/useCallback/useRef/React.memo/useMemo

文章目录 项目地址十六、useContecxt十七、useReducer十八、React.memo以及产生的问题18.1组件嵌套的渲染规律18.2 React.memo18.3 引出问题 十九、useCallback和useMemo19.1 useCallback对函数进行缓存19.2 useMemo19.2.1 基本的使用19.2.2 缓存属性数据 19.2.3 对于更新的理解…...

ISUP协议视频平台EasyCVR萤石设备视频接入平台银行营业网点安全防范系统解决方案

在金融行业,银行营业厅的安全保卫工作至关重要,它不仅关系到客户资金的安全,也关系到整个银行的信誉和运营效率。随着科技的发展,传统的安全防护措施已经无法满足现代银行对于高效、智能化安全管理的需求。 EasyCVR视频汇聚平台以…...

Ubuntu20.04下安装向日葵

向日葵远程控制app官方下载 - 贝锐向日葵官网 下载Ununtu版的图形版本的安装deb包SunloginClient_15.2.0.63064_amd64.deb 直接执行 sudo dpkg -i SunloginClient_15.2.0.63064_amd64.deb 的话会报错: 如果在Ubuntu20.04里直接执行sudo apt install libgconf-2-4安装libgco…...

sql工具!好用!爱用!

SQLynx的界面设计简洁明了,操作逻辑清晰易懂,没有复杂的图标和按钮,想对哪部分操作就在哪里点击右键,即使你是数据库小白也能轻松上手。 尽管SQLynx是一款免费的工具,但是它的功能却丝毫不逊色于其他付费产品&#xff…...