提示:要直接看搭建例子的能够跳到 三java
一.项目架构的发展web
传统的mvc架构项目将整个系统功能实现所有写在一个项目中,部署在一个机器上,随着用户量的增涨,单个项目服务器没法承受暴增的用户请求时须要增长服务器数量,并经过负载均衡集群将项目部署到多个服务器上,提升项目可处理的用户请求总数。spring
当mvc架构项目中的某个或某几个模块的用户请求量较大,其余模块用户请求量较小,此时负载均衡集群依然是每一个服务器部署一个完整的项目,实际须要进行负载均衡的仅是用户请求量较大的几个模块,此处则可采用分布式将系统功能模块服务化。spring-mvc
在项目过于庞大,部署单项目没法知足需求时,须要将项目的不一样功能模块拆分红单独的服务项目部署到不一样的服务器上(也就是分布式)。tomcat
在分布式中,各个服务项目之间要进行相互调用,须要在知道地址的状况下经过网络进行访问。此时须要一个能让全部服务都能得知其余服务地址的中间人,由此产生了服务注册中心,服务项目须要告诉服务注册中心它是干吗的,也就是进行服务注册,服务器
当其余项目要调用特定服务时能够到服务注册中心查找服务项目的地址,获取到服务项目地址后便可经过网络地址自行调用该服务项目,这整个过程涉及的结构也就是rpc架构的内容。网络
rpc架构:架构
包含服务提供者、服务消费者、服务注册中心;mvc
服务注册中心:在服务提供者进行服务注册时保存服务提供者信息,在服务消费者进行服务发现时返回服务提供者地址;app
服务提供者provider:在服务注册中心进行服务注册,等待服务消费者调用;
服务消费者consumer:在服务注册中心进行服务发现,在获得服务注册中心返回的服务提供者地址后进行服务调用;
rpc架构缺点:当项目拆分服务过多时没法得知服务是否正在被谁使用;
soa服务化架构:在rpc架构的基础上加了服务治理系统;
二.Zookeeper与Dubbo分别是什么?各自在项目中充当什么角色?
Zookeeper是什么:
Apache ZooKeeper是由集群(节点组)使用的一种服务,用于在自身之间协调,并经过稳健的同步技术维护共享数据。ZooKeeper自己是一个分布式应用程序,为写入分布式应用程序提供服务。
zookeeper充当的角色:
在上述rpc架构中zookeeper就是一个服务注册中心,全部的服务都在zookeeper中进行登记(服务注册),当某个服务要调用其余服务时,问zookeeper要该服务的网络地址(服务发现)。
dubbo是什么:
Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
dubbo充当的角色:
rpc架构的系统中全部服务项目都须要进行服务注册(告诉服务注册中心我是谁)与服务发现(告诉服务注册中心我要找谁),服务提供者和服务消费者(也就是服务自己)可以使用dubbo来负责服务注册与服务发现。
dubbo对rpc架构缺点的处理:
Dubbo提供了dubbo-admin服务治理系统,在搭建dubbo+zookeeper后可运行dubbo-admin系统进行服务管理,也就从rpc架构变成了soa服务化架构。
三.搭建dubbo+zookeeper小例子
在正式搭建前能够先安装并启动zookeeper(略),随后安装dubbo-admin,下载dubbo-admin.war,更名ROOT.war,放到tomcat中,启动后可修改其中的dubbo.properties,将地址和帐号密码修改为你安装的zookeeper的,随后重启项目
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest
而后能够访问localhost:8080(修改成ROOT.war就是为了能localhost:8080直接访问项目),登陆dubbo-admin后能够进去逛逛
在搭建到步骤3或步骤4时能够启动项目,而后到dubbo-admin服务管理系统中查看消费者和提供者是否有对应的数据,能够此为依据,判断服务是否注册成功。
1.建立maven项目,并在项目中建立三个子项目,service项目用于编写公共服务接口,dubboProvider去实现service中的接口,dubboConsumer用于调用公共服务接口在dubboProvider中的实现
2.在service项目中新增一个接口:
package com.lwl.service; public interface DemoService { String sayHello(String name); }
3.dubboProvider中的操做:
3-1)在dubboProvider项目的pom.xml中加入依赖
<!--公共服务接口依赖--> <dependency> <groupId>com.lwl</groupId> <artifactId>service</artifactId> <version>1.0</version> </dependency> <!--dubbo依赖 https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.10</version> <!-- 排除dubbo依赖自带的spring和netty依赖,防止自带的依赖与项目内依赖版本冲突,若是自己项目没有,无需排除 --> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> <exclusion> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> </exclusion> </exclusions> </dependency> <!--zkclient依赖 https://mvnrepository.com/artifact/com.101tec/zkclient --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.11</version> </dependency> <!--dubbo自身的spring相关依赖被排除,此处将dubbo所须要的对应依赖引入--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.1.8.RELEASE</version> </dependency>
3-2)建立DemoServiceImpl 类,实现公共服务接口
package com.lwl.service.impl; import com.lwl.service.DemoService; public class DemoServiceImpl implements DemoService { @Override public String sayHello(String name) { return "Hello " + name; } }
3-3)在web.xml中配置启动spring
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- 启动spring容器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
3-4)在applicationContext.xml中
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--启动扫描--> <context:component-scan base-package="com.lwl.service"/> <!--声明公共服务接口实现类的bean--> <bean id="demoService" class="com.lwl.service.impl.DemoServiceImpl"/>
<!--dubbo:application:提供方的应用名--> <dubbo:application name="dubbo-provider"/> <!--dubbo:registry:注册中心的类型和地址--> <dubbo:registry address="zookeeper://127.0.0.1:2181" check="false" subscribe="false" register=""/> <!--dubbo:protocol:这个服务要暴露在哪一个端口上(使用方根据这个端口使用服务)--> <dubbo:protocol name="dubbo" port="20880"/> <!--dubbo:service:设置暴露的服务接口,ref 为该接口的 bean,timeout 为超时时间--> <dubbo:service interface="com.lwl.service.DemoService" ref="demoService" timeout="600000"/> </beans>
4.在dubboConsumer项目中的操做:
4-1)在dubboConsumer项目的pom.xml文件添加依赖:
<!--公共服务接口依赖--> <dependency> <groupId>com.lwl</groupId> <artifactId>service</artifactId> <version>1.0</version> </dependency> <!--dubbo依赖 https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.10</version> <!-- 排除dubbo自带的spring和netty,使用项目的包,若是自己项目没有则无需排除 --> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> <exclusion> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> </exclusion> </exclusions> </dependency> <!--zkclient依赖 https://mvnrepository.com/artifact/com.101tec/zkclient --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.11</version> </dependency> <!-- SpringMVC: https://mvnrepository.com/artifact/org.springframework/spring-webmvc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.8.RELEASE</version>
</dependency>
4-2)在web.xml中启动springmvc
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- SpringMVC核心控制器 --> <servlet> <servlet-name>spring-mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring-mvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
4-3)在spring-mvc.xml中
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <!-- 注解探测器--> <context:component-scan base-package="com.lwl.controller"/> <context:annotation-config/> <!--dubbo:application: 使用方的应用名--> <dubbo:application name="dubbo-consumer"/> <!--dubbo:registry:注册中心的类型和地址--> <dubbo:registry address="zookeeper://127.0.0.1:2181" check="false"/> <!--dubbo:reference:要使用的服务的接口,并将返回的注入 bean,名称为id设的值--> <dubbo:reference interface="com.lwl.service.DemoService" id="demoService"/> <!-- 注册注解驱动 --> <mvc:annotation-driven/> </beans>
4-4)建立controller:
package com.lwl.controller; import com.lwl.service.DemoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class DemoController { // @Autowired // 默认按byType自动注入,当找不到对应类型的bean时才按byName自动注入,都找不到时抛出异常 // 默认状况下必需要求依赖对象必须存在,若是要容许null值可以使用@Autowired(required=false) // @Resource // 默认按byName自动注入,找不到时抛出异常 @Resource//或使用@Autowired(required = false) private DemoService demoService; @GetMapping("/{name}") public String get(@PathVariable String name) { return demoService.sayHello(name); } }
5.先启动dubboProvider项目,随后启动dubboConsumer项目,启动后访问http://localhost:8080/dubboConsumer/** 返回 Hello ** 则配置成功