基于dubbo的项目开发

2,163 阅读12分钟

dubbo是什么: dubbo是一个阿里巴巴开发的开源分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴集团的各成员站点的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持。dubbo是对一个系统中应用层上的优化,后面我会在对系统中数据库层面的优化进行分享,这里我们只针对dubbo进行学习

dubbo能解决什么问题: 当网站变大后,不可避免的需要拆分应用进行服务化,以提高系统性能,开发效率等。并且要求拆分出去的每个服务可以根据需要灵活的配置它的集群数量和控制服务的粒度(服务的粒度就是说我运行的服务系统中对外发布的服务数量)

dubbo的优点: 1、使用简单 2、部署轻盈 3、方便二次开发 当当网:dubboX 京东:jd-hydra 这些都是基于dubbo二次开发的框架

在学习dubbo之前我们先来了解一下分布式应用

分布式应用.png

分布式应用:应用程序分布在不同计算机上,通过网络来共同完成一项任务。通常为服务端/客户端模式。 服务器/客户端又分为二端(server/client)、三端(server/middleware/client)、N端(multiple server/multiple minddle/multiple client)。也就是说分布式应用需要把服务(service)拆分出来,单独部署在一个web服务器中,controller调用service就通过网络来调用,这就形成了客户端和服务端的模式,客户端只负责运行controller代码,处理数据请求和响应;服务端只负责业务处理,数据运算等。又因为原本一个系统既需要处理用户的请求和响应,又需要处理业务流程,运行压力会比较大,从而影响整个系统的性能。现在把系统一分为二了,这就大大的提高整个系统的性能了

三端分布式应用.png

N端分布式应用.png

上面说到了分布式的应用分成客户端和服务端,它们各自运行在自己的服务器中,客户端的controller调用服务端的service就不是在一个应用内调用了,而是通过网络传输来调用。 这种通过网络来使controller调用远程的service的技术叫做RPC技术

RPC原理.png

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)

先使用xml方式来写一个hello world程序

这里我使用的工具是idea 先创建一个父项目(dubbo_parent),然后再创建三个模块

1,创建三个项目

一个用于服务端,一个用于客户端,一个用于接口 服务端: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>

项目关系.png

2、添加springboot相关依赖和导入dubbo相关依赖(在dubbo_parent父项目的pom.xml中添加)

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、编写接口程序

3.1 首先我们在domain包里创建一个HelloWorld的实体类,定义一个属性 name,提供setter,getter方法实现Serializable接口 3.2 其次我们在service包里创建一个接口定义一个抽象方法

4、编写服务端程序(接口实现类)和创建启动类

创建服务端的启动类

@SpringBootApplication
@ImportResource("classpath:dubbo-server.xml")
public class StartApp {
    public static void main(String[] args) {
        SpringApplication.run(StartApp.class,args);
    }
}
5、编写服务端xml配置(dubbo-service.xml)
  <!--把具体的服务实现类交给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"/>

6、编写客户端xml配置
  <!--设置应用名-->
    <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"/>

7、编写客户端程序(启动类)
@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全注解的方式构建)

基于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应用的启动类

修改pom.xml

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>

创建两个服务端启动类 StartApp shop_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);
    }
}

三、各个服务系统整合mybatis

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

四、各个服务系统整合mybatis-generator插件

1、在各个服务系统的pom文件中添加mybatis-generator插件(在pom.xml已经添加) 2、在resources目录下添加generatorConfig.xml文件(两个服务系统需要适当的修改)

五、各个服务系统整合dubbo发布服务程序

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应用

七、各个客户端整合dubbo引用服务程序

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

八、引用服务(以商品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();
    }
}