美文网首页
总结-dubbo入门.跨域访问

总结-dubbo入门.跨域访问

作者: xc2023 | 来源:发表于2019-03-10 14:42 被阅读0次
  • 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
dubbo1.png dubbo2.png

wutong-api

dubbo3.png

wutong-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

相关文章

  • 总结-dubbo入门.跨域访问

    soa-面向服务架构 rpc-远程过程调用协议 dubbo-分布式.高性能,透明化的rpc框架 核心+ provi...

  • 【ES6】var、let、const三者的区别

    总结1.var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。2.let定义的变量,只能在块作用域里访问...

  • 跨域

    什么是跨域访问 跨域访问,简单来说就是 A 网站的 javascript 代码试图访问 C网站,包括提交内容和获取...

  • 跨域

    参考资料 HTTP访问控制(CORS)跨域解决方案跨域详解

  • C# Web直接上传视频或者文件到OSS

    代码 解决本地调试跨域问题 设置跨域规则:找到OSS存储——Bucket列表——基础设置——跨域访问——设置 暴露...

  • Android WebView高风险问题解决

    A.WebView跨域访问漏洞: 在Android应用中,WebView开启了file域访问,允许file域访问h...

  • window.URL 与 跨域

    跨域 关于跨域问题,简单来说就是通过地址访问资源时,所用的协议不同导致无法访问目标。 网上已经有很多关于跨域的主流...

  • spring boot 配置跨域问题

    跨域 配置静态文件访问

  • 使用CORS解决跨域问题

    1.跨域问题 1.1 什么是跨域 跨域是指跨域名的访问,以下情况都属于跨域: 如果域名和端口都相同,但是请求路径不...

  • H5跨域访问

    跨域访问是源于浏览器的同源策略而引申出来的概念 1、先了解什么是同源策略和跨域访问 同源策略、跨域解决方案 - R...

网友评论

      本文标题:总结-dubbo入门.跨域访问

      本文链接:https://www.haomeiwen.com/subject/eqsupqtx.html