dubbo是什么:dubbo是一个阿里巴巴开发的开源分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴集团的各成员站点的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持。dubbo是对一个系统中应用层上的优化,后面我会在对系统中数据库层面的优化进行分享,这里我们只针对dubbo进行学习
dubbo能解决什么问题:当网站变大后,不可避免的需要拆分应用进行服务化,以提高系统性能,开发效率等。并且要求拆分出去的每个服务可以根据需要灵活的配置它的集群数量和控制服务的粒度(服务的粒度就是说我运行的服务系统中对外发布的服务数量)
dubbo的优点:1、使用简单 2、部署轻盈 3、方便二次开发 当当网:dubboX 京东:jd-hydra 这些都是基于dubbo二次开发的框架
分布式应用:应用程序分布在不同计算机上,通过网络来共同完成一项任务。通常为服务端/客户端模式。 服务器/客户端又分为二端(server/client)、三端(server/middleware/client)、N端(multiple server/multiple minddle/multiple client)。也就是说分布式应用需要把服务(service)拆分出来,单独部署在一个web服务器中,controller调用service就通过网络来调用,这就形成了客户端和服务端的模式,客户端只负责运行controller代码,处理数据请求和响应;服务端只负责业务处理,数据运算等。又因为原本一个系统既需要处理用户的请求和响应,又需要处理业务流程,运行压力会比较大,从而影响整个系统的性能。现在把系统一分为二了,这就大大的提高整个系统的性能了
上面说到了分布式的应用分成客户端和服务端,它们各自运行在自己的服务器中,客户端的controller调用服务端的service就不是在一个应用内调用了,而是通过网络传输来调用。 这种通过网络来使controller调用远程的service的技术叫做 RPC技术 。
RPC技术是什么: RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务 RPC的原理: 就是对象的序列化、反序列化以及序列化后数据的传输,dubbo(使用二进制文件,TCP) java领域常见的RPC框架: Java领域里的分布式技术或者说分布式框架叫做RPC框架有:Dubbo,ZeroICE
使用分布式的模式的优点? 1.在开发上,分成了多个系统,有利于开发任务的分配,各自负责各自的系统开发。 2.在运行上,把负载压力分配到多台服务器上,提高整个系统的运行性能。 3.由于分布式开发模式是把业务或者功能以服务的形式对外发布,这样的话可以提高服务重用率
用了dubbo的优点? 拆分应用进行服务化,提高系统性能,开发效率,并且可以灵活配置服务集群数和控制服务
注册中心的作用: 1、服务端服务的注册和客户端服务的调用 2、提高系统的可用性 3、提高系统的可伸缩性 4、集中管理服务
注册中心有什么: zookeeper: zooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
zookeeper的使用虽然能提供给dubbo应用做注册中心的技术有很多,但是我们用的是zookeeper,因为它是dubbo官方推荐的技术,在springboot-dubbo中,也是默认整合了zookeeper。而且zookeeper它是Hadoop和HBase的重要组件,如果后期项目需要发展大数据业务,那么就可以无缝的接入大数据的技术。所以我们使用zookeeper作为基于dubbo框架的分布式系统的注册中心。
1,下载zookeeper运行程序 进入zookeeper官网: zookeeper.apache.org/下载 2,修改配置文件 zoo_sample.cfg修改成zoo.cfg(可以copy一份再修改) # 内存数据的备份地址 dataDir=F://zookeeper-3.4.5//data
dataLogDir=F://zookeeper-3.4.5//log
复制代码
3,双击bin目录下的zkServer.cmd,运行zookeeper(如果是Mac路径就不说了,启动需要到bin目录下在终端使用命令 sh zkServer.sh start)
这里我使用的工具是idea 先创建一个父项目(dubbo_parent),然后再创建三个模块
一个用于服务端,一个用于客户端,一个用于接口 服务端:server 客户端:client 接口:api 然后我们来修改pom.xml配置,这了api项目只是提供接口不需要继承dubbo_parent的依赖所以在api的pom.xml里取消继承的配置. 同时我们在server和client需要api的接口,所以我们需要在server,client两个项目中导入api的依赖
<dependencies>
<dependency>
<groupId>com.jd.dubbo</groupId>
<artifactId>api</artifactId>
</dependency>
</dependencies>
复制代码
springboot父项目:spring-boot-starter-parent springbootweb相关项目spring-boot-starter-web
<!--Spring Boot项目-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<dependencies>
<!--spring-boot-web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- dubbo相关依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--zookeeper-->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.2</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.5</version>
</dependency>
</dependencies>
复制代码
3.2 其次我们在service包里创建一个接口定义一个抽象方法
创建服务端的启动类
@SpringBootApplication @ImportResource("classpath:dubbo-server.xml") public class StartApp { public static void main(String[] args) { SpringApplication.run(StartApp.class,args); } } 复制代码
<!--把具体的服务实现类交给spring容器管理--> <bean id="helloWorld" class="com.jd.dubbo.service.impl.HelloWorldServiceImpl"/> <!--设置应用名--> <dubbo:application name="dubbo-server"/> <!--设置RPC协议--> <dubbo:protocol name="dubbo" port="20880"/> <!--设置注册中心地址zookeeper,register属性,默认是true,如果为true的化,就需要把发布的服务的服务地址注册到zookeeper 如果为false,就不需要把服务的地址注册到zookeeper中 --> <!--<dubbo:registry address="zookeeper://127.0.0.1:2181" register="false"/>--> <dubbo:registry address="zookeeper://127.0.0.1:2181" register="true" file="${user.home}/dubbo.cache"/> <!--发布服务--> <dubbo:service interface="com.jd.dubbo.service.IHelloWorldService" ref="helloWorld"/> 复制代码
<!--设置应用名--> <dubbo:application name="dubbo-client"/> <!--设置注册中心地址zookeeper--> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <!--引用服务--> <dubbo:reference interface="com.jd.dubbo.service.IHelloWorldService" id="helloWorldService"/> 复制代码
@SpringBootApplication @ImportResource("classpath:dubbo-client.xml") @Controller public class StartApp { @Autowired private IHelloWorldService helloWorldService; public static void main (String[] args){ SpringApplication.run(StartApp.class,args); } @RequestMapping("/sayHello") @ResponseBody public String sayHello(){ HelloWorld helloWorld =helloWorldService.sayHello(new HelloWorld()); return helloWorld.getName(); } } 复制代码
到这里我们通过xml的配置方式已经完成了,我们先启动服务端server再启动客服端client
基于springboot全注解的方式构建的好处 1、Springboot给我们提供了一整套开发包,导入一个依赖就能使用它给我们提供的对应的功能,提高我们的开发效率 2、减少了我们应用自己导入依赖包的数量 3、省去了繁琐的xml配置文件 4、内嵌web服务器:如tomcat,jetty,部署应用变得方便 5、用springboot整合dubbo可以很方便的开发分布式的微服务
一、创建各个工程项目
shop_parent shop_api_goods(商品系统的api) shop_api_order(订单系统的api) shop_server_goods(商品系统) shop_server_order(订单系统) shop_client_mgrsite(后台管理系统) shop_clinet_website(移动端接口)
先创建一个父项目然后再创建其他模块,在shop_parent的pom.xml添加以下依赖
<!--Spring Boot项目-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<dependencies>
<!--spring-boot-web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Dubbo 依赖 -->
<dependency>
<groupId>io.dubbo.springboot</groupId>
<artifactId>spring-boot-starter-dubbo</artifactId>
<version>1.0.0</version>
<!--剔除Dubbo内的netty,因为zookeeper中有一个-->
<exclusions>
<exclusion>
<artifactId>netty</artifactId>
<groupId>org.jboss.netty</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!--管理商品之间的依赖-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.jd.shop</groupId>
<artifactId>shop_api_goods</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.jd.shop</groupId>
<artifactId>shop_api_order</artifactId>
<version>1.0</version>
</dependency>
<!--阿里巴巴的druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.25</version>
</dependency>
<!--spring-boot的mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!--用于打包和启动springBoot应用的插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
复制代码
二、添加项目相关依赖 1、添加springboot项目 2、添加我们需要用到的服务系统api包 3、添加springboot-web依赖 4、添加连接数据库的相关依赖 5、添加dubbo依赖 6、创建springboot应用的启动类
1.在shop_api_goods(商品系统的api)shop_server_goods(商品系统)这两个模块中不需要继承shop_parent所以在他们的pom.xml中需要修改一下. 2.分别在在shop_server_goods(商品系统和shop_server_order(订单系统)中添加依赖,
<!--shop_server_goods-->
<dependency>
<groupId>com.jd.shop</groupId>
<artifactId>shop_api_goods</artifactId>
</dependency>
复制代码
<!--shop_server_order-->
<dependency>
<groupId>com.jd.shop</groupId>
<artifactId>shop_api_order</artifactId>
</dependency>
复制代码
<!--shop_server_order--> <!--shop_server_order--> <dependencies> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--阿里巴巴的druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <!--spring-boot的mybatis依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <verbose>true</verbose> <overwrite>false</overwrite> </configuration> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency> </dependencies> </plugin> </plugins> </build> 复制代码
创建两个服务端启动类 StartAppshop_server_goods和shop_server_order的启动类
@SpringBootApplication @EnableTransactionManagement @MapperScan("com.jd.server.goods.mapper") public class StartApp { public static void main(String[] args) { SpringApplication.run(StartApp.class,args); } } 复制代码
1、在application.properties配置文件中添加如下配置信息:(两个服务需要做部分修改,需要修改的地方下面在()里标注了)
server.port=9090(server.port=9091) #数据库连接地址 spring.datasource.url=jdbc:mysql://localhost:3306/jd_shop #MySQL驱动 spring.datasource.driverClassName=com.mysql.jdbc.Driver #数据库账号 spring.datasource.username=root #数据库密码 spring.datasource.password=123456 #阿里巴巴Druid连接池 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource #mybatis的mapper.xml配置文件路径 mybatis.mapperLocations=classpath:mapper/*.xml #mybatis的mapper.xml配置文件domain对象别名扫描路径 mybatis.typeAliasesPackage=com.jd.api.goods.domain (mybatis.typeAliasesPackage=com.jd.api.order.domain ) 复制代码
2、在启动类添加如下注解:(上面的启动类代码已经添加了)
//扫描mybatis接口的注解 @MapperScan("com.jd.server.goods.mapper") //开启事务管理 @EnableTransactionManagement 复制代码
1、在各个服务系统的pom文件中添加mybatis-generator插件(在pom.xml已经添加) 2、在resources目录下添加generatorConfig.xml文件(两个服务系统需要适当的修改)
1、在application.properties配置文件中添加如下配置信息:
#整合dubbo #设置应用的服务名 spring.dubbo.application.name=shop-server-goods (spring.dubbo.application.name=shop-server-order) #设置RPC协议 spring.dubbo.protocol.name=dubbo #设置RPC端口号 spring.dubbo.protocol.port=20880 #设置注册中心的地址 spring.dubbo.registry.address=zookeeper://127.0.0.1:2181 #设置发布服务注解扫描的路径 spring.dubbo.scan=com.jd.server.goods.service.impl (spring.dubbo.scan=com.jd.server.order.service.impl) 复制代码
1、使用mybatis-genenrator插件生成domain类、mapper接口、mapper.xml文件 2、每个domain类应该在对应的api项目中 3、在对应的api项目中创建一个服务接口
4、创建服务实现类 在该实现类上贴上@Service注解,贴上了该注解就代表了该类需要发布服务
注意:1、该注解是com.alibaba.dubbo.config.annotation包下的注解不是spring的注解 2、贴上该注解的服务实现类必须要在上面的配置项spring.dubbo.scan=xxx能够扫描到的路径下
5、启动springboot应用
1、在application.properties配置文件中添加如下配置信息:
#dubbo应用名 spring.dubbo.application.name=shop-client-mgrsite #连接的注册中心地址 spring.dubbo.registry.address=zookeeper://127.0.0.1:2181 #引用服务扫描的路径 spring.dubbo.scan=com.jd.client.mgrsite.controller 复制代码
1、创建商品的controller调用商品的服务 在该controller需要注入服务的依赖上贴上@Refrence注解,贴上该注解就可以自动的把需要引用的服务注入进来 注意:贴上该注解的服务依赖必须要在上面的配置项spring.dubbo.scan=xxx能够扫描到的路径下
@Controller public class ProductController { @Reference IProductService productService; @RequestMapping("/getAllProduct") @ResponseBody public List<Product> getAllProduct() { return productService.getAllProduct(); } } 复制代码