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

SpringCloud微服务:基于Nacos组件,整合Dubbo框架

dubbo和fegin的差异

一、Feign与Dubbo概述
Feign是一个声明式的Web服务客户端,使得编写HTTP客户端变得更简单。通过简单的注解,Feign将自动生成HTTP请求,使得服务调用更加便捷。而Dubbo是一个高性能、轻量级的Java RPC框架,提供了丰富的服务治理功能。

二、性能对比
调用性能:在单次调用方面,Feign的性能表现略逊于Dubbo。由于Feign的自动生成HTTP请求机制,其性能相较于Dubbo的直接RPC调用会有一定的损失。然而,对于大多数应用而言,这种性能差异并不明显。
负载均衡:Feign和Dubbo都提供了负载均衡功能。Feign使用Ribbon作为其负载均衡组件,而Dubbo则内置了负载均衡机制。在负载均衡方面,Dubbo提供了更多的配置选项和策略,具有更强的灵活性。
服务发现:Feign依赖于Eureka、Consul、Nacos等注册中心实现服务发现,而Dubbo则提供了内置的服务发现机制。在服务发现的性能和稳定性方面,Dubbo具有一定的优势。


三、区别分析
架构差异:Feign基于SpringCloud体系,更适用于微服务架构。而Dubbo则独立于任何框架,具有更强的通用性。
适用场景:对于简单的服务调用场景,Feign更加简洁易用。而当需要复杂的服务治理功能时,Dubbo则更具优势。
扩展性:Feign提供了丰富的注解和配置选项,可以轻松地与SpringCloud的其他组件集成。而Dubbo则提供了丰富的SPI机制,使得扩展更加灵活。
社区活跃度:Feign的社区相对活跃,随着SpringCloud的发展,Feign也在不断迭代和完善。Dubbo的社区虽然活跃度不如Feign,但凭借其多年的积累和沉淀,依然拥有大量的用户和稳定的支持者。

项目代码

项目结构图:

整体结构比较简单,两个服务提供者、一个消费者、一个接口定义模块。

先看各个模块的maven配置:

父工程pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.0.RELEASE</version><relativePath/> </parent><groupId>com.zwm</groupId><artifactId>dubbo-demo</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>common-api</module><module>consumer</module><module>provider1</module><module>provider2</module></modules><properties><java.version>8</java.version><com.alibaba.cloud.version>2.2.3.RELEASE</com.alibaba.cloud.version><org.spring.cloud.version>Hoxton.SR8</org.spring.cloud.version><org.spring.boot.version>2.3.2.RELEASE</org.spring.boot.version></properties><dependencyManagement><!--使用management一次性依赖多个parent项目--><dependencies><!--springboot start依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>${org.spring.boot.version}</version><!--添加type和scope标签 并设置为pom和import 要不子模块引不到这些依赖--><type>pom</type><scope>import</scope></dependency><!--springCloudAlibaba 依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${com.alibaba.cloud.version}</version><!--添加type和scope标签 并设置为pom和import 要不子模块引不到这些依赖--><type>pom</type><scope>import</scope></dependency><!--springCloud依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${org.spring.cloud.version}</version><!--添加type和scope标签 并设置为pom和import 要不子模块引不到这些依赖--><type>pom</type><scope>import</scope><exclusions><!--因为后续要用dubbo去做远程调用 所以这里就把openfeign的依赖给排除掉--><exclusion><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></exclusion></exclusions></dependency></dependencies></dependencyManagement>
</project>

服务提供者pom:两个服务提供者配置一样,这样就只展示一个。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>dubbo-demo</artifactId><groupId>com.zwm</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>provider2</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--nacos配置中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--nacos注册中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><exclusions><exclusion><artifactId>httpclient</artifactId><groupId>org.apache.httpcomponents</groupId></exclusion></exclusions></dependency><!--dubbo与springboot自动装配starter--><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.8</version><exclusions><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion><exclusion><artifactId>spring-context</artifactId><groupId>org.springframework</groupId></exclusion></exclusions></dependency><!--dubbo - > nacos注册--><dependency><groupId>com.alibaba</groupId><artifactId>dubbo-registry-nacos</artifactId><version>2.7.7</version><exclusions><exclusion><artifactId>nacos-client</artifactId><groupId>com.alibaba.nacos</groupId></exclusion></exclusions></dependency><dependency><groupId>com.zwm</groupId><artifactId>common-api</artifactId><version>1.0-SNAPSHOT</version><scope>compile</scope></dependency></dependencies>
</project>

消费者pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>dubbo-demo</artifactId><groupId>com.zwm</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>consumer</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--nacos配置中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--nacos注册中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><exclusions><exclusion><artifactId>httpclient</artifactId><groupId>org.apache.httpcomponents</groupId></exclusion></exclusions></dependency><!--dubbo与springboot自动装配starter--><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.8</version><exclusions><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion><exclusion><artifactId>spring-context</artifactId><groupId>org.springframework</groupId></exclusion></exclusions></dependency><!--dubbo - > nacos注册--><dependency><groupId>com.alibaba</groupId><artifactId>dubbo-registry-nacos</artifactId><version>2.7.7</version><exclusions><exclusion><artifactId>nacos-client</artifactId><groupId>com.alibaba.nacos</groupId></exclusion></exclusions></dependency><dependency><groupId>com.zwm</groupId><artifactId>common-api</artifactId><version>1.0-SNAPSHOT</version><scope>compile</scope></dependency></dependencies>
</project>

common-api的pom里面就不需要特殊的配置了。

接下来看nacos、dubbo的属性配置。

服务提供者:application.yaml;

server:port: 8081
spring:application:name: dubbo-provider2 #应用名称cloud:nacos:discovery:server-addr: 127.0.0.1:8848 #nacos服务与发现地址enabled: false #设置false 关闭nacos服务注册与发现 让dubbo自己往nacos进行注册
# dubbo configuration
dubbo:registry:address: nacos://127.0.0.1:8848use-as-config-center: false #不使用配置中心 要不他会往配置中心注册一个当前application.name的配置protocol:name: dubboport: -1 #自动创建端口

两个服务提供者配置基本一样,除了端口和应用名称外。

消费者:application.yaml

server:port: 8082
spring:application:name: spring-boot-dubbo-consumercloud:nacos:discovery:enabled: false #设置false属性 不让nacos自己注册 让dubbo去注册server-addr: 127.0.0.1:8848group: DEFAULT_GROUP# dubbo configuration
dubbo:registry:address: nacos://127.0.0.1:8848use-as-config-center: false #不使用配置中心 要不他会往配置中心注册一个当前application.name的配置protocol:name: dubboport: -1cloud:subscribed-services: 'dubbo-provider1,dubbo-provider2' #配置订阅服务多个服务用,隔开,不配置默认订阅注册中心所有服务

项目需要的相关配置基本就配置完成了,下面简单看下代码:

common-api里面就是简单的定义了接口:

package com.zwm.api;public interface DemoService {String getString(String name);
}

服务提供者,两个服务基本一样,就是实现了上面的接口:

先看服务提供者的启动类:

package com.zwm;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** Hello world!*/
@SpringBootApplication
@EnableDubbo(scanBasePackages = "com.zwm.service")
public class Provider1Application {public static void main(String[] args) {SpringApplication.run(Provider1Application.class, args);}
}
package com.zwm.service.impl;import com.zwm.api.DemoService;
import org.apache.dubbo.config.annotation.DubboService;@DubboService
public class ProviderServiceTest implements DemoService {@Overridepublic String getString(String name) {return "provider1 say: hello!" + name;}
}

注意上面的@DubboService注解,这个很重要!!!用于暴露服务。启动类上面需要添加:@EnableDubbo(服务提供者才需要添加,消费者启动类不需要!!!),开启dubbo,(scanBasePackages = "com.zwm.service")这个如果配置文件里面配置了扫包的路径这里可以不需要。

消费者:去调用暴露的服务:

package com.zwm.controller;import com.zwm.api.DemoService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import javax.websocket.server.PathParam;@RestController
public class ConsumerDemoController {@DubboReferenceprivate DemoService demoService;@GetMapping("/demo")public String hello(@PathParam("name") String name) {return demoService.getString(name);}
}

注意添加:@DubboReference注解!!!

服务启动要先启动服务提供者,启动后可以在nacos上看到注册的服务:

点开详情,可以查看详细的信息:端口号、应用名称、接口方法定义等等。

如果在启动的过程中出现了: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass。

那么这个时候需要在启动的时候添加如下参数:--add-opens java.base/java.lang=ALL-UNNAMED

再启动另一个服务提供者:

这时候就会看到另一个服务提供者也上来了,大家可能会发现名称有点不一样,有一个实例数还是2,那是因为其中一个服务提供者暴露了两个服务。

接下来启动消费者:
 

这个时候消费者也上来了,可以在浏览器输入地址进行访问测试:http://localhost:8082/my?name=zwm123

如果你也能看到这样的效果,那么恭喜大家springcloud基于Nacos组件,整合Dubbo框架就实现了。

如果大家觉得配置起来很麻烦,也可以直接下载:https://download.csdn.net/download/javaweiming/90265288

相互学习、共同进步...

相关文章:

SpringCloud微服务:基于Nacos组件,整合Dubbo框架

dubbo和fegin的差异 一、Feign与Dubbo概述 Feign是一个声明式的Web服务客户端&#xff0c;使得编写HTTP客户端变得更简单。通过简单的注解&#xff0c;Feign将自动生成HTTP请求&#xff0c;使得服务调用更加便捷。而Dubbo是一个高性能、轻量级的Java RPC框架&#xff0c;提供了…...

Golang 简要概述

文章目录 1. Golang 的学习方向2. Golang 的应用领域2.1 区块链的应用开发2.2 后台的服务应用2.3 云计算/云服务后台应用 1. Golang 的学习方向 Go 语言&#xff0c;我们可以简单的写成 Golang 2. Golang 的应用领域 2.1 区块链的应用开发 2.2 后台的服务应用 2.3 云计算/云服…...

web前端第三次作业---制作可提交的用户注册表

制作可提交的用户注册表: 代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</tit…...

教育邮箱的魔力:免费获取Adobe和JetBrains软件

今天想和大家聊聊一个超级实用的话题——如何利用Edu教育邮箱来免费获取Photoshop等Adobe系列软件&#xff0c;以及JetBrains的各种开发工具。 Edu邮箱的价值 首先&#xff0c;Edu邮箱真的是个宝藏&#xff01;如果你在学校或教育机构注册过&#xff0c;通常会获得一个这样的…...

sympy常用函数与错误笔记

文章目录 前言一、sympy基本函数介绍变量定义1. sp.Symbol("x") 或 sp.symbols("m n")2. sp.Function("y")3. func(x).diff(x, n) 定义方程与求解符号1. sp.Eq(lhs, rhs)2. 求解函数&#xff08;*代表了常用且重要&#xff0c;其他部分作为拓展&…...

47_Lua文件IO操作

文件I/O(Input/Output)操作在Lua中用于与外部文件进行交互,包括读取文件中的数据和将数据写入文件。Lua提供了两种模式来进行文件操作:简单模式和完全模式。下面将详细介绍这两种模式的基本使用。 1.简单模式 1.1 简单模式介绍 简单模式提供了基本的文件操作功能,它主要…...

nginx-lua模块处理流程

一. 简述&#xff1a; nginx的模块化设计使得每一个http模块可以只专注于完成一个独立的&#xff0c;简单的功能。一个请求的完整处理过程可以由多个http模块共同协作完成&#xff0c;这种设计具有简单性&#xff0c;测试性&#xff0c;扩展性&#xff0c;灵活性。关于nginx 的…...

【大数据】机器学习-----最开始的引路

以下是关于机器学习的一些基本信息&#xff0c;包括基本术语、假设空间、归纳偏好、发展历程、应用现状和代码示例&#xff1a; 一、基本术语 样本&#xff08;Sample&#xff09;&#xff1a; 也称为实例&#xff08;Instance&#xff09;或数据点&#xff08;Data Point&…...

【前端】自学基础算法 -- 21.图的广度优先搜索

图的广度优先搜索 简介 图的广度优先搜索&#xff0c;沿着图的宽度遍历图的节点&#xff0c;先访问离起始节点最近的节点&#xff0c;然后逐渐向外扩展。 基本步骤&#xff1a; 选择一个起始节点作为当前节点。将当前节点加入队列。当队列不为空时&#xff0c;重复以下步骤…...

ChatGPT与Claude AI:两大生成式对话模型的比较分析

自ChatGPT推出以来&#xff0c;这款强大的AI聊天机器人迅速吸引了全球的关注。其出色的对话能力和多样化的应用场景&#xff0c;成为许多人初次体验基于大规模语言模型的潜力。然而&#xff0c;在这个快速发展的领域中&#xff0c;另一款AI也在悄然崭露头角&#xff0c;那就是由…...

前端开发:盒子模型、块元素

1.border边框 *{box-sizing:border-box; } //使所有边框不再撑大盒子模型 粗细 : border-width 样式 : border-style, 默认没边框 . solid 实线边框 dashed 虚线边框 dotted 点线边框 颜色 : border-color div { width : 200px ; height : 200px ; border : …...

升级 CentOS 7.x 系统内核到 4.4 版本

问题描述 在 CentOS 7.x 系统中&#xff0c;默认内核版本是 3.10.x&#xff0c;这个版本可能会带来一些与 Docker 和 Kubernetes 兼容性的问题&#xff0c;导致系统性能不稳定或功能异常。为了提高系统的稳定性和兼容性&#xff0c;建议升级到更高版本的内核&#xff0c;例如 …...

播放音频文件同步音频文本

播放音频同步音频文本 对应单个文本高亮显示 使用audio音频文件对应音频文本资源 音频文本内容&#xff08;Json&#xff09; [{"end": 4875,"index": 0,"speaker": 0,"start": 30,"text": "70号二啊,","tex…...

springboot使用Easy Excel导出列表数据为Excel

springboot使用Easy Excel导出列表数据为Excel Easy Excel官网&#xff1a;https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write 主要记录一下引入时候的pom&#xff0c;直接引入会依赖冲突 解决方法&#xff1a; <!-- 引入Easy Excel的依赖 -->&l…...

day07_Spark SQL

文章目录 day07_Spark SQL课程笔记一、今日课程内容二、Spark SQL函数定义&#xff08;掌握&#xff09;1、窗口函数2、自定义函数背景2.1 回顾函数分类标准:SQL最开始是_内置函数&自定义函数_两种 2.2 自定义函数背景 3、Spark原生自定义UDF函数3.1 自定义函数流程&#x…...

高性能现代PHP全栈框架 Spiral

概述 Spiral Framework 诞生于现实世界的软件开发项目是一个现代 PHP 框架&#xff0c;旨在为更快、更清洁、更卓越的软件开发提供动力。 特性 高性能 由于其设计以及复杂精密的应用服务器&#xff0c;Spiral Framework框架在不影响代码质量以及与常用库的兼容性的情况下&a…...

LeetCode - #182 Swift 实现找出重复的电子邮件

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…...

《解锁鸿蒙Next系统人工智能语音助手开发的关键步骤》

在当今数字化时代&#xff0c;鸿蒙Next系统与人工智能的融合为开发者带来了前所未有的机遇&#xff0c;开发一款人工智能语音助手应用更是备受关注。以下是在鸿蒙Next系统上开发人工智能语音助手应用的关键步骤&#xff1a; 环境搭建与权限申请 安装开发工具&#xff1a;首先需…...

【Linux网络编程】数据链路层 | MAC帧 | ARP协议

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 &#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系…...

《自动驾驶与机器人中的SLAM技术》ch7:基于 ESKF 的松耦合 LIO 系统

目录 基于 ESKF 的松耦合 LIO 系统 1 坐标系说明 2 松耦合 LIO 系统的运动和观测方程 3 松耦合 LIO 系统的数据准备 3.1 CloudConvert 类 3.2 MessageSync 类 4 松耦合 LIO 系统的主要流程 4.1 IMU 静止初始化 4.2 ESKF 之 运动过程——使用 IMU 预测 4.3 使用 IMU 预测位姿进…...

编写程序实现钓鱼浮标刻度雕刻,防水不褪色,输出钓友精准看口,实用刚需。

应用到广大钓友最关心的“眼睛”——钓鱼浮标&#xff08;浮漂&#xff09;上。我们要解决的是户外垂钓中一个既专业又恼人的问题&#xff1a;浮标刻度的防水与清晰度。项目方案&#xff1a;基于Python的钓鱼浮标激光刻度精密雕刻系统一、 实际应用场景描述想象一下&#xff0c…...

云原生应用的可观测性最佳实践

云原生应用的可观测性最佳实践 &#x1f525; 硬核开场 各位技术老铁&#xff0c;今天咱们聊聊云原生应用的可观测性最佳实践。别跟我扯那些理论&#xff0c;直接上干货&#xff01;在云原生时代&#xff0c;可观测性是系统可靠性的关键&#xff0c;它能帮助我们全面了解系统…...

ROS Noetic下,用DWA和TEB调教你的机器人:move_base局部规划器参数实战避坑指南

ROS Noetic下DWA与TEB局部规划器参数调优实战指南 1. 理解局部规划器的核心作用 在ROS导航堆栈中&#xff0c;局部规划器扮演着机器人运动控制的"末梢神经"角色。当全局规划器生成了一条从起点到终点的理想路径后&#xff0c;局部规划器负责根据实时环境信息&#xf…...

OpenClaw+Phi-3-vision-128k-instruct低成本方案:自建多模态助手避坑指南

OpenClawPhi-3-vision-128k-instruct低成本方案&#xff1a;自建多模态助手避坑指南 1. 为什么选择本地部署多模态助手 去年我尝试用商业API搭建个人知识管理助手时&#xff0c;发现两个痛点&#xff1a;一是处理PDF和图片的token消耗像流水一样快&#xff0c;二是长文档分析…...

利用快马AI快速原型:十分钟搭建软件下载站首页与详情页

最近在帮朋友做一个软件下载站的原型&#xff0c;要求能快速上线测试用户反馈。传统开发方式从设计到编码至少需要一周&#xff0c;但这次我用InsCode(快马)平台的AI生成功能&#xff0c;十分钟就搞定了基础框架&#xff0c;分享下具体实现思路。 首页布局设计 首页需要突出展示…...

2026届毕业生推荐的十大AI辅助论文平台解析与推荐

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 于学术写作范畴之内&#xff0c;论文AI工具已然变成提高研究效率的关键辅助法子。当下主流工…...

别再瞎调RAG了!用RAGAS给你的LangChain应用做个“体检报告”(附完整代码)

用RAGAS为你的LangChain应用做深度诊断&#xff1a;从指标解读到精准优化 当你花费数周构建的RAG系统突然在关键演示中输出"纽约市得名于一位爱吃苹果的市长"时&#xff0c;那种绝望感我深有体会。去年我们的客服机器人就曾把"产品退货政策"解释成"建…...

你的旧笔记本也能跑AI了:用Ollama+WSL在Windows上低成本体验大模型

在Windows旧笔记本上低成本运行AI大模型的完整指南 你是否也曾经对着那些需要高端显卡才能运行的AI大模型望而却步&#xff1f;现在&#xff0c;即使是一台配置普通的Windows笔记本&#xff0c;也能轻松体验大语言模型的魅力。本文将带你一步步实现这个看似不可能的任务——不需…...

3大优势!Scarab模组管理工具使用技巧:从新手到高手的进阶指南

3大优势&#xff01;Scarab模组管理工具使用技巧&#xff1a;从新手到高手的进阶指南 【免费下载链接】Scarab An installer for Hollow Knight mods written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/sc/Scarab 你是否在安装空洞骑士模组时遇到过文件路…...

Windows USB开发新范式:使用UsbDk突破系统限制实现设备独占访问

Windows USB开发新范式&#xff1a;使用UsbDk突破系统限制实现设备独占访问 【免费下载链接】UsbDk Usb Drivers Development Kit for Windows 项目地址: https://gitcode.com/gh_mirrors/us/UsbDk 痛点识别&#xff1a;传统USB开发面临的挑战 当你尝试在Windows平台上…...