- soa-面向服务架构
- rpc-远程过程调用协议
- dubbo-分布式.高性能,透明化的rpc框架
- 核心
+ provider: 服务提供者
+ consumer: 服务消费者
+ container: dubbo容器.依赖于spring容器
+ register: 注册中心 zookeeper/redis/multicast/simple
+ monitor: 监听器 - 运行原理:
+ 启动容器,相当于在启动Dubbo的Provider
+ 启动后会去注册中心进行注册.注册所有可以提供的服务列表
+ 在Consumer启动后会去Registry中获取服务列表和Provider的地址.进行订阅.
+ 当Provider有修改后,注册中心会把消息推送给Consummer
+ 使用了观察者设计模式(又叫发布/订阅设计模式)
+ 根据获取到的Provider地址,真实调用Provider中功能.
+ 在Consumer方使用了代理设计模式.创建一个Provider方类的一个代理对象.通过代理对象获取Provider中真实功能,起到保护 Provider真实功能的作用.
+ Consumer和Provider每隔1分钟向Monitor发送统计信息,统计信息包含,访问次数,频率等.
实例
新建一个空文件.新建四个项目
- wutong-api (jar): 要暴露的接口
- wutong-web(web): 前端
- wutong-gateway(web) dubbo-provider
- wutong-order(jar): dubbo-consumer
wutong-api
dubbo3.pngwutong-order
作为服务的提供者.需要依赖wutong-api并实现其中的接口,引入依赖
(build 里是打jar包用的)
<?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>
<groupId>com.order</groupId>
<artifactId>wutong-order</artifactId>
<version>1.0-SNAPSHOT</version>
<name>wutong-order</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.3</version>
</dependency>
<dependency>
<groupId>com.api</groupId>
<artifactId>wutong-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
<build>
<!--打成jar的名称-->
<finalName>project-service</finalName>
<resources>
<resource>
<targetPath>${project.build.directory}/classes</targetPath>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<!-- 结合com.alibaba.dubbo.container.Main,因为dubbo自带的Main需要读取classes/META-INF/spring下的spring配置信息 -->
<resource>
<targetPath>${project.build.directory}/classes/META-INF/spring</targetPath>
<directory>src/main/resources/spring</directory>
<filtering>true</filtering>
<includes>
<!--将spring相关的配置文件拷贝到classes/META-INF/spring下 -->
<include>application-dubbo.xml</include>
</includes>
</resource>
</resources>
<plugins>
<!-- 配置manifest文件,以及服务jar的启动类 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<classesDirectory>target/classes/</classesDirectory>
<archive>
<manifest>
<!--执行Jar文件的启动类,使用dubbo自带的启动类 -->
<mainClass>com.alibaba.dubbo.container.Main</mainClass>
<!-- 打包时 MANIFEST.MF文件不记录的时间戳版本 -->
<useUniqueVersions>false</useUniqueVersions>
<addClasspath>true</addClasspath>
<!--将服务依赖的jar文件,放到lib文件夹下 -->
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<!-- 将运行服务的jar文件,依赖的其它jar文件放在lib文件夹下 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<type>jar</type>
<includeTypes>jar</includeTypes>
<outputDirectory>
${project.build.directory}/lib </outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
dubbo配置文件
<?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:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="provider"/>
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://192.168.116.150:2181"/>
<!-- 用dubbo协议在29014端口暴露服务 -->
<dubbo:protocol name="dubbo" port="29014"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.api.UserService"
ref="userService"/>
<!-- 具体的实现bean -->
<bean id="userService" class="com.order.service.UserServiceImpl"/>
</beans>
实现类
package com.order.service;
import com.api.UserService;
public class UserServiceImpl implements UserService {
@Override
public void say() {
System.out.printf("say something");
}
@Override
public void write() {
System.out.printf("write something");
}
@Override
public void play() {
System.out.printf("play something");[图片上传中...(dubbo4.png-7340e0-1552193745777-0)]
}
}
打包是要先打包wutong-api,然后在打包wutong-order
dubbo4.png
运行 注意打包后的文件在target下, lib里是依赖的jar包 ,每次更改项目都需要重新打包
dubbo5.png
启动
[图片上传中...(dubbo7.png-8459bf-1552194459352-0)]
zookeeper里新增了dubbo的节点
dubbo7.png
wutong-gateway :consumer
作为服务的消费者,也需要依赖wutong-api ,是个web项目.引入springmvc的依赖
dubbo8.png
dubbo9.png
dubbo的配置文件
<?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:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="consumer"/>
<!-- 使用multicast广播注册中心暴露发现服务地址 -->
<dubbo:registry protocol="zookeeper" address="zookeeper://192.168.116.150:2181"/>
<!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id="userService" interface="com.api.UserService"/>
</beans>
dubbo里的bean也可以当做spring的bean直接使用
dubbo10.png
启动项目,访问controller
dubbo11.png
跨域访问,
同源是指"协议+域名+端口"三者相同
三个任意一个不同就是跨域
新建一个maven的web项目,只做前端访问用
新建head.html. 里面访问wutong-gateway的controller,项目端口不同.所以是跨域
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<link href="../css/bootstrap.min.css" rel="stylesheet">
<script src="../js/jquery-3.0.0.js"></script>
<script src="../js/vue.js"></script>
</head>
<body>
<div class="container" id="app">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<ul class="nav nav-tabs nav-justified">
<li role="presentation" :class="{head}" @click="sendUser(head)">首页</li>
<li role="presentation" :class="{user}" @click="sendUser(user)">用户中心</li>
<li role="presentation" :class="{order}" @click="sendUser(order)">订单中心</li>
<li role="presentation" :class="{pay}" @click="sendUser(pay)">支付中心</li>
<li role="presentation" :class="{cangku}" @click="sendUser(cangku)">仓库中心</li>
<li role="presentation" :class="{manager}" @click="sendUser(manager)">管理中心</li>
</ul>
</div>
</div>
<div class="row">
<div v-if="'head'==active" class="col-md-8 col-md-offset-2">head</div>
<div v-else-if="'user'==active" class="col-md-8 col-md-offset-2">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<input type="email" v-model="email" placeholder="email">
<input type="password" v-model="password" placeholder="password">
<button type="button" class="btn btn-success" @click="login">登陆</button>
</div>
</div>
</div>
<div v-else-if="'order'==active" class="col-md-8 col-md-offset-2">order</div>
<div v-else-if="'pay'==active" class="col-md-8 col-md-offset-2">pay</div>
<div v-else-if="'cangku'==active" class="col-md-8 col-md-offset-2">cangku</div>
<div v-else-if="'manager'==active" class="col-md-8 col-md-offset-2">manager</div>
</div>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
head:'head',
user:'user',
order:'order',
pay:'pay',
cangku:'cangku',
manager:'manager',
active:"head",
email:'',
password:'',
},
methods:{
sendUser : function (e) {
this.active=e;
},
login:function () {
/*$.ajax({
url:"http://localhost:9000/user/login",
type:'GET',
data:{email:this.email,password:this.password},
success:function (data) {
console.log(data)
}
});*/
$.ajax({
url:"http://localhost:9001/gateway/user/login",
type:'GET',
dataType:'jsonp',
jsonp:"callback",
jsonpCallback:"success",
data:{email:this.email,password:this.password},
success:function (data) {
console.log(data)
}
});
},
}
})
</script>
</body>
</html>
jquery的jsonp需要服务端的配合,我们知道 jsonp依赖的是script标签的src属性,所以返回的数据是js类型的才会解析,服务端需要将数据先转为json类型,然后在拼接为js
访问login接口
dubbo14.png
jsonp服务端配合略显麻烦,还有另一种策略在服务端的返回头里加
response.addHeader("Access-Control-Allow-Origin", "*");
*可以替换为具体的域名
新建一个springboot项目,wutong-manager
@RestController
@RequestMapping("user")
public class UserController {
@RequestMapping("/login")
public String login(@RequestParam String email,
@RequestParam String password,
HttpServletResponse response){
System.out.println(email+password);
return "success";
}
}
每个单独加太麻烦,直接在拦截器里加请求头
自定义拦截器
@Component
public class HeadInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.addHeader("Access-Control-Allow-Origin", "http://localhost:9002");
System.out.println("lan jie qi");
//response.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
添加拦截器
@Component
public class AllInterceptor extends WebMvcConfigurationSupport {
@Autowired
private HeadInterceptor headInterceptor;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(headInterceptor).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
dubbo15.png
访问测试
dubbo16.png
总结
dubbo入门
jquery的jsnop
springboot 拦截器
github地址:https://github.com/cailonghao/zongjie
网友评论