NServiceBus---最流行的开源企业服务总线 for .Net资源学习篇
2012-04-09 11:05
609 查看
NServiceBus是dotnet世界里面最流行的开源企业服务总线. 它具有以下特点:
1.强大,轻量级
2.可插拨,简单易用
3.支持企业级开发
零安装,在五分钟内就可以实现订阅/发布,如果你正在使用WCF,BizTalk,WebSphere or Sonic,你应该考虑一下NServiceBus:
1.NServiceBus and WCF
2.NServiceBus and BizTalk
3.NServiceBus and WebSphere/Sonic
NServiceBus开始于2006年,并且一直在持续的改进,而且社区很活跃,作者更新的也很快.而且NServiceBus已经被多个大公司应用到正式的实际生产项目中,还是经受过正式项目的考验的,在这里可以查看一下NServiceBus的性能。
现在NserviceBus将要发布2.0版本,开发使用起来相当友好和方便,插拨性相当强,甚至连容器都可以替换。
Learn more about NServiceBus...
官方地址:http://www.nservicebus.com/
相关的资源
1.NServiceBus——让创建企业级.NET系统更加容易
2.NService yahoo group
3.官方文档
作者:孤独侠客(似水流年)
出处:http://lonely7345.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
NServiceBus 是一个用于构建企业级 .NET系统的开源通讯框架。它在消息发布/订阅支持、工作流集成和高度可扩展性等方面表现优异,因此是很多分布式系统基础平台的理想选择。,它能够帮助开发人员在搭建企业.NET系统时避免很多典型的常见问题。同时,该框架也提供了一些可伸缩的关键特征,比如对发布/订阅的支持、集成的长时间工作流及深入的扩展能力等。据作者说,其本意是为构建分布式应用软件创建一个理想的基础设施。
NServiceBus的核心并不依赖于MSMQ。NServiceBus可扩展性允许我们插入自行编写的通信传送器,、订阅存储器和工作流的实现。我已经基于MSMQ实现了一个传送器,还有一个则借助了WCF的NetTCP。开发人员既可以使用这些现有组件,也可以根据需要进行自定义。我们知道当前的许多SOA产品都与HTTP紧密耦合,因此NServiceBus的这种实现方式也将是个另辟蹊径的设计。
之所以选择使用MSMQ,是因为它是微软公司的两大主流的通讯技术之一(另一个是SQL Server Service Broker)。MSMQ允许双方在离线的状态下进行通信,且它提供了一整套易于使用的API,并已经集成到了.NET框架中,这一点要比Service Broker好得多。我个人认为支持离线通信是任何SOA基础框架都必须考虑的关键部分——因为Tenet of Service Autonomy 并不能保证当前通信的另一端处于可用状态。
NServiceBus是dotnet世界里面最流行的开源企业服务总线. 它具有以下特点: 1.强大,轻量级. 2.可插拨,简单易用. 3.支持企业级开发.
在internet中的应用
Publish / Subscribe (发布者/订阅者)
²这种方式解决了发布消息对象知道消息发送给谁.(谁订阅了就给谁发)
Subscriptions (订阅者)
Publish(发布者)
NserviceBus in Distributor(在分布式系统的应用)
One publish(一个发布者):
Two publish(两个发布者的时候):
Point to Point(点对点通信)
Point to Point Configuration(需要配置)
?
?
Request & Response(请求\回复)
Publish & Subscribe(发布者\订阅者)
?
?
Saga(Workflow)
?
Distributor(分布式系统)
?
NServiceBus 是一个用于构建企业级 .NET系统的开源通讯框架。它在消息发布/订阅支持、工作流集成和高度可扩展性等方面表现优异,因此是很多分布式系统基础平台的理想选择。,它能够帮助开发人员在搭建企业.NET系统时避免很多典型的常见问题。同时,该框架也提供了一些可伸缩的关键特征,比如对发布/订阅的支持、集成的长时间工作流及深入的扩展能力等。据作者说,其本意是为构建分布式应用软件创建一个理想的基础设施。
NServiceBus的核心并不依赖于MSMQ。NServiceBus可扩展性允许我们插入自行编写的通信传送器,、订阅存储器和工作流的实现。我已经基于MSMQ实现了一个传送器,还有一个则借助了WCF的NetTCP。开发人员既可以使用这些现有组件,也可以根据需要进行自定义。我们知道当前的许多SOA产品都与HTTP紧密耦合,因此NServiceBus的这种实现方式也将是个另辟蹊径的设计。
之所以选择使用MSMQ,是因为它是微软公司的两大主流的通讯技术之一(另一个是SQL Server Service Broker)。MSMQ允许双方在离线的状态下进行通信,且它提供了一整套易于使用的API,并已经集成到了.NET框架中,这一点要比Service Broker好得多。我个人认为支持离线通信是任何SOA基础框架都必须考虑的关键部分——因为Tenet of Service Autonomy 并不能保证当前通信的另一端处于可用状态。
NServiceBus是dotnet世界里面最流行的开源企业服务总线. 它具有以下特点: 1.强大,轻量级. 2.可插拨,简单易用. 3.支持企业级开发.
NServiceBus官网:http://www.nservicebus.com 可以在那里下载到最近版本的代码.
解压缩后如下图所示
先运行RunMeFirst.bat 然后再运行build.bat(因为我的是vs2008)结果如下图:
会多出binaries和build两个文件夹
而后需要安装windows message queue(百度一下,你就知道).
在管理里面就可以看到有message queueing了.接下来开发安装
如我所示,你需要的是在build后生成的build文件夹里的host里面NServiceBus.Host.exe安装.这个我开始在src里面代码里运行都出错了.
之后把工作编译通过.
运行MyPublisher,你会发现如下结果:
再查看msessage queue 你会发现:
有9个message 己经存到subscriber1 inputqueue里了
再运行subscriber1 你会发现
己经接收到在message queue里的信息.
作者:spring yang
出处:http://www.cnblogs.com/springyangwc/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
项目介绍:
项目名称叫Workflow, 是为一家在荷兰的呼叫中心客户化定制开发一款帮助他们管理工作流的系统。这个系统采用Domain Driven Design作为整个项目的总体设计方案。商业逻辑(business logic)在Domain model实现,Domain model用POCO(plain old c# object)实现,Domain model凭借fluent nhibernate map到数据库。Web部分采用ASP.NET MVC 2.0,StructureMap做为IoC container, 所以在controller里面就可以方便的使用接口I*whatever*Service来inject服务层。 当然了,项目中用到Messaging的部分是借用NserviceBus实现的。
因为整个系统中频繁用到给用户发邮件的功能,所以下面我就给大家介绍一下如果用NServiceBus实现Email messaging.
0. 在MVC project Web.config文件中,添加下面的配置, 主要目的是设置发送出去的message到达的终点站。
1 <UnicastBusConfig>
2 <MessageEndpointMappings>
3 <add Messages="Workflow.Messages.Email.EmailMessage, Workflow.Messages" Endpoint="EmailQueue"/>
4 </MessageEndpointMappings>
5 </UnicastBusConfig>
6
1. 在Controller constructor 里面inject IEmailService
1 public AdministratorsController(IUserMailer userMailer)
2 {
3 this.userMailer = userMailer;
4 }
2. 大家注意第10行,当新添加一个administrator之后,调用userMailer服务,来给这个新添加的管理员发送密码。
1 public Url Post(AddAdministratorViewModel model)
2 {
3 if (!ModelState.IsValid)
4 {
5 return model;
6 }
7
8 var administrator = administratorFactory.Create(model.UserName, model.Email);
9 adminRepository.Add(administrator);
10 userMailer.SendPasswordNotification(administrator);
11
12 returnnew AdministratorUrl { Administrator = administrator };
13 }
3. 接下来在ApplicationService层里,UserMailer类继承IUserMailer, 同样在UserMailer constructor里面 inject IBus. IBus是NServiceBus的接口。
1 public UserMailer(IBus bus)
2 {
3 this.bus = bus;
4 }
4. 第8行创建一个新的EmailMessage对象, 第9行用bus 发送这个对象。
1 publicvoid SendPasswordNotification(User user)
2 {
3 if (user ==null)
4 {
5 thrownew ArgumentNullException("user");
6 }
7
8 var email =new EmailMessage("from", "to", "title", "body");
9 bus.Send(email);
10 }
5. EmailMessage 类需要继承IMessage, IMessage是NServiceBus的一个接口,表明这个类符合NServiceBus对Message的定义,同时可以被NServiceBus处理。
1 publicclass EmailMessage : IMessage
2 {
3 // EmailMessage implementation goes here;
4 }
6. 最后一个环节就是在Solution中创建一个新的class library, 可以作为background service来实际发送邮件。在实现这个class library的时候,有基本上有3个方面需要注意:
1). App.config, 第4, 5, 7三行是特别用来配置NServiceBus. 在MsmqTransportConfig这一行,确保InputQueue是你在第0步骤中设定的Message要达到终点站的名字
1 <?xml version="1.0"?>
2 <configuration>
3 <configSections>
4 <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core"/>
5 <section name="Logging" type="NServiceBus.Config.Logging, NServiceBus.Core"/>
6 </configSections>
7 <MsmqTransportConfig ErrorQueue="error" InputQueue="EmailQueue" MaxRetries="5" NumberOfWorkerThreads="1"/>
8 <startup>
9 <supportedRuntime sku=".NETFramework,Version=v4.0" version="v4.0"/>
10 </startup>
11 </configuration>
2). MessageEndPoint.cs, 这个类继承了NServiceBus的几个接口, IConfiureThisEndpoint (表明这个类是终点站的配置类), AsA_Server(表明这个终点站是个服务器), IWantCustomerInitialization(表明我们需要自己的container 和 serializer)
1 publicclass MessageEndpoint : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
2 {
3 publicvoid Init()
4 {
5 Configure.With()
6 .StructureMapBuilder(ObjectFactory.Container)
7 .XmlSerializer();
8 }
9 }
3). EmailHandler.cs: 当EmailMessage 这个类型的message到达中间站的时候,我们要对这个message的操作在此类中实现。在本例中,我们首先获得一个SmtpClient的实例,然后用我们的EmailMessage来创建一个System.Net.Mail.MailMessage的实例mail,最后用smtpclient将这个mail发送。搞定!
1 publicclass EmailHandler : IHandleMessages<EmailMessage>
2 {
3 publicvoid Handle(EmailMessage message)
4 {
5 try
6 {
7 var client =new SmtpClient();
8 var htmlBody ="blah";
9 var mail =new MailMessage(message.From, message.To);
10
11 client.Send(mail);
12 }
13 catch (SmtpFailedRecipientsException)
14 {
15 // mail cannot be sent due to recipient specific error
16 }
17 }
18 }
当你实现了上面六个环节之后,在visual studio中设定"Set Startup Project", 选中新创建的class library。接下来F5, 你会发现除了正常的MVC项目启动之外,还有一个background application 也会同时启动。当你在系统中新创建一个管理员时,NServiceBus将向你的管理员发送他首次登陆密码。
希望这篇文章对大家在了解和使用NSerivecBus搭建SOA类型的项目时,有一定的帮助。期待看到越来越多的人喜欢上NServiceBus。
1.强大,轻量级
2.可插拨,简单易用
3.支持企业级开发
零安装,在五分钟内就可以实现订阅/发布,如果你正在使用WCF,BizTalk,WebSphere or Sonic,你应该考虑一下NServiceBus:
1.NServiceBus and WCF
2.NServiceBus and BizTalk
3.NServiceBus and WebSphere/Sonic
NServiceBus开始于2006年,并且一直在持续的改进,而且社区很活跃,作者更新的也很快.而且NServiceBus已经被多个大公司应用到正式的实际生产项目中,还是经受过正式项目的考验的,在这里可以查看一下NServiceBus的性能。
现在NserviceBus将要发布2.0版本,开发使用起来相当友好和方便,插拨性相当强,甚至连容器都可以替换。
Learn more about NServiceBus...
官方地址:http://www.nservicebus.com/
相关的资源
1.NServiceBus——让创建企业级.NET系统更加容易
2.NService yahoo group
3.官方文档
作者:孤独侠客(似水流年)
出处:http://lonely7345.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
初步理解NServiceBus
概述NServiceBus 是一个用于构建企业级 .NET系统的开源通讯框架。它在消息发布/订阅支持、工作流集成和高度可扩展性等方面表现优异,因此是很多分布式系统基础平台的理想选择。,它能够帮助开发人员在搭建企业.NET系统时避免很多典型的常见问题。同时,该框架也提供了一些可伸缩的关键特征,比如对发布/订阅的支持、集成的长时间工作流及深入的扩展能力等。据作者说,其本意是为构建分布式应用软件创建一个理想的基础设施。
NServiceBus的核心并不依赖于MSMQ。NServiceBus可扩展性允许我们插入自行编写的通信传送器,、订阅存储器和工作流的实现。我已经基于MSMQ实现了一个传送器,还有一个则借助了WCF的NetTCP。开发人员既可以使用这些现有组件,也可以根据需要进行自定义。我们知道当前的许多SOA产品都与HTTP紧密耦合,因此NServiceBus的这种实现方式也将是个另辟蹊径的设计。
之所以选择使用MSMQ,是因为它是微软公司的两大主流的通讯技术之一(另一个是SQL Server Service Broker)。MSMQ允许双方在离线的状态下进行通信,且它提供了一整套易于使用的API,并已经集成到了.NET框架中,这一点要比Service Broker好得多。我个人认为支持离线通信是任何SOA基础框架都必须考虑的关键部分——因为Tenet of Service Autonomy 并不能保证当前通信的另一端处于可用状态。
NServiceBus是dotnet世界里面最流行的开源企业服务总线. 它具有以下特点: 1.强大,轻量级. 2.可插拨,简单易用. 3.支持企业级开发.
在internet中的应用
Publish / Subscribe (发布者/订阅者)
²这种方式解决了发布消息对象知道消息发送给谁.(谁订阅了就给谁发)
Subscriptions (订阅者)
Publish(发布者)
NserviceBus in Distributor(在分布式系统的应用)
One publish(一个发布者):
Two publish(两个发布者的时候):
Point to Point(点对点通信)
Point to Point Configuration(需要配置)
?
Publish & Subscribe(发布者\订阅者)
?
?
?
NServiceBus的安装与调试
概述NServiceBus 是一个用于构建企业级 .NET系统的开源通讯框架。它在消息发布/订阅支持、工作流集成和高度可扩展性等方面表现优异,因此是很多分布式系统基础平台的理想选择。,它能够帮助开发人员在搭建企业.NET系统时避免很多典型的常见问题。同时,该框架也提供了一些可伸缩的关键特征,比如对发布/订阅的支持、集成的长时间工作流及深入的扩展能力等。据作者说,其本意是为构建分布式应用软件创建一个理想的基础设施。
NServiceBus的核心并不依赖于MSMQ。NServiceBus可扩展性允许我们插入自行编写的通信传送器,、订阅存储器和工作流的实现。我已经基于MSMQ实现了一个传送器,还有一个则借助了WCF的NetTCP。开发人员既可以使用这些现有组件,也可以根据需要进行自定义。我们知道当前的许多SOA产品都与HTTP紧密耦合,因此NServiceBus的这种实现方式也将是个另辟蹊径的设计。
之所以选择使用MSMQ,是因为它是微软公司的两大主流的通讯技术之一(另一个是SQL Server Service Broker)。MSMQ允许双方在离线的状态下进行通信,且它提供了一整套易于使用的API,并已经集成到了.NET框架中,这一点要比Service Broker好得多。我个人认为支持离线通信是任何SOA基础框架都必须考虑的关键部分——因为Tenet of Service Autonomy 并不能保证当前通信的另一端处于可用状态。
NServiceBus是dotnet世界里面最流行的开源企业服务总线. 它具有以下特点: 1.强大,轻量级. 2.可插拨,简单易用. 3.支持企业级开发.
NServiceBus官网:http://www.nservicebus.com 可以在那里下载到最近版本的代码.
解压缩后如下图所示
先运行RunMeFirst.bat 然后再运行build.bat(因为我的是vs2008)结果如下图:
会多出binaries和build两个文件夹
而后需要安装windows message queue(百度一下,你就知道).
在管理里面就可以看到有message queueing了.接下来开发安装
如我所示,你需要的是在build后生成的build文件夹里的host里面NServiceBus.Host.exe安装.这个我开始在src里面代码里运行都出错了.
之后把工作编译通过.
运行MyPublisher,你会发现如下结果:
再查看msessage queue 你会发现:
有9个message 己经存到subscriber1 inputqueue里了
再运行subscriber1 你会发现
己经接收到在message queue里的信息.
作者:spring yang
出处:http://www.cnblogs.com/springyangwc/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
轻轻松松SOA: NServiceBus
上周跟一位猎头在google talk上聊了几句,被问道有没有WCF, WF的经验,汗!对于WCF, WF,没有任何经验,但是这并不代表着我对SOA没有任何应验,其实去年一年,我们都是在用NerviceBus作为实现SOA的工具。百度了一下,发现有个园友似水流年已经写过一篇介绍NServiceBus的文章,“NServiceBus---最流行的开源企业服务总线 for .Net”。那我就不再雷同,今天就给大家介绍一下如何在实际项目中使用NServiceBus。项目介绍:
项目名称叫Workflow, 是为一家在荷兰的呼叫中心客户化定制开发一款帮助他们管理工作流的系统。这个系统采用Domain Driven Design作为整个项目的总体设计方案。商业逻辑(business logic)在Domain model实现,Domain model用POCO(plain old c# object)实现,Domain model凭借fluent nhibernate map到数据库。Web部分采用ASP.NET MVC 2.0,StructureMap做为IoC container, 所以在controller里面就可以方便的使用接口I*whatever*Service来inject服务层。 当然了,项目中用到Messaging的部分是借用NserviceBus实现的。
因为整个系统中频繁用到给用户发邮件的功能,所以下面我就给大家介绍一下如果用NServiceBus实现Email messaging.
0. 在MVC project Web.config文件中,添加下面的配置, 主要目的是设置发送出去的message到达的终点站。
1 <UnicastBusConfig>
2 <MessageEndpointMappings>
3 <add Messages="Workflow.Messages.Email.EmailMessage, Workflow.Messages" Endpoint="EmailQueue"/>
4 </MessageEndpointMappings>
5 </UnicastBusConfig>
6
1. 在Controller constructor 里面inject IEmailService
1 public AdministratorsController(IUserMailer userMailer)
2 {
3 this.userMailer = userMailer;
4 }
2. 大家注意第10行,当新添加一个administrator之后,调用userMailer服务,来给这个新添加的管理员发送密码。
1 public Url Post(AddAdministratorViewModel model)
2 {
3 if (!ModelState.IsValid)
4 {
5 return model;
6 }
7
8 var administrator = administratorFactory.Create(model.UserName, model.Email);
9 adminRepository.Add(administrator);
10 userMailer.SendPasswordNotification(administrator);
11
12 returnnew AdministratorUrl { Administrator = administrator };
13 }
3. 接下来在ApplicationService层里,UserMailer类继承IUserMailer, 同样在UserMailer constructor里面 inject IBus. IBus是NServiceBus的接口。
1 public UserMailer(IBus bus)
2 {
3 this.bus = bus;
4 }
4. 第8行创建一个新的EmailMessage对象, 第9行用bus 发送这个对象。
1 publicvoid SendPasswordNotification(User user)
2 {
3 if (user ==null)
4 {
5 thrownew ArgumentNullException("user");
6 }
7
8 var email =new EmailMessage("from", "to", "title", "body");
9 bus.Send(email);
10 }
5. EmailMessage 类需要继承IMessage, IMessage是NServiceBus的一个接口,表明这个类符合NServiceBus对Message的定义,同时可以被NServiceBus处理。
1 publicclass EmailMessage : IMessage
2 {
3 // EmailMessage implementation goes here;
4 }
6. 最后一个环节就是在Solution中创建一个新的class library, 可以作为background service来实际发送邮件。在实现这个class library的时候,有基本上有3个方面需要注意:
1). App.config, 第4, 5, 7三行是特别用来配置NServiceBus. 在MsmqTransportConfig这一行,确保InputQueue是你在第0步骤中设定的Message要达到终点站的名字
1 <?xml version="1.0"?>
2 <configuration>
3 <configSections>
4 <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core"/>
5 <section name="Logging" type="NServiceBus.Config.Logging, NServiceBus.Core"/>
6 </configSections>
7 <MsmqTransportConfig ErrorQueue="error" InputQueue="EmailQueue" MaxRetries="5" NumberOfWorkerThreads="1"/>
8 <startup>
9 <supportedRuntime sku=".NETFramework,Version=v4.0" version="v4.0"/>
10 </startup>
11 </configuration>
2). MessageEndPoint.cs, 这个类继承了NServiceBus的几个接口, IConfiureThisEndpoint (表明这个类是终点站的配置类), AsA_Server(表明这个终点站是个服务器), IWantCustomerInitialization(表明我们需要自己的container 和 serializer)
1 publicclass MessageEndpoint : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
2 {
3 publicvoid Init()
4 {
5 Configure.With()
6 .StructureMapBuilder(ObjectFactory.Container)
7 .XmlSerializer();
8 }
9 }
3). EmailHandler.cs: 当EmailMessage 这个类型的message到达中间站的时候,我们要对这个message的操作在此类中实现。在本例中,我们首先获得一个SmtpClient的实例,然后用我们的EmailMessage来创建一个System.Net.Mail.MailMessage的实例mail,最后用smtpclient将这个mail发送。搞定!
1 publicclass EmailHandler : IHandleMessages<EmailMessage>
2 {
3 publicvoid Handle(EmailMessage message)
4 {
5 try
6 {
7 var client =new SmtpClient();
8 var htmlBody ="blah";
9 var mail =new MailMessage(message.From, message.To);
10
11 client.Send(mail);
12 }
13 catch (SmtpFailedRecipientsException)
14 {
15 // mail cannot be sent due to recipient specific error
16 }
17 }
18 }
当你实现了上面六个环节之后,在visual studio中设定"Set Startup Project", 选中新创建的class library。接下来F5, 你会发现除了正常的MVC项目启动之外,还有一个background application 也会同时启动。当你在系统中新创建一个管理员时,NServiceBus将向你的管理员发送他首次登陆密码。
希望这篇文章对大家在了解和使用NSerivecBus搭建SOA类型的项目时,有一定的帮助。期待看到越来越多的人喜欢上NServiceBus。
相关文章推荐
- NServiceBus---最流行的开源企业服务总线 for .Net
- NServiceBus---最流行的开源企业服务总线 for .Net
- NServiceBus-.Net平台下开源的服务总线(open-source service for .net)
- NServiceBus---最流行的开源企业服务总线AND让创建企业级.NET系统更加容易
- ESB企业服务总线 --- Enterprise Service Bus
- 企业服务总线Enterprise service bus介绍
- 【转载】企业服务总线Enterprise service bus介绍
- 企业服务总线Enterprise service bus介绍
- 企业总线Enterprise Service Bus
- Microsoft通过Service Bus for Windows把云整合服务搬到本地
- Mono For Android 服务service的学习(1)--本地服务
- (7)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- 利用Polly+AOP+依赖注入封装的降级框架
- (9)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- JWT算法
- (10)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Ocelot+Identity Server
- 轻量级企业服务总线Mule学习记录
- (5)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- 熔断降级(Polly)
- 开源企业服务总线ESB汇总与对比
- (11)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Thrift高效通讯 (完结)
- Azure Messaging-ServiceBus Messaging消息队列技术系列8-服务总线配额
- 开源企业服务总线ESB汇总与对比