分布式程序开发

分布式的应用

  • 手机应用;
  • 手机app(前台应用)
  • java管理程序(后台应用)

后台应用功能拆分,不同的应用可以部署在不同的机器上;不同应用程序之间也需要互相调用;

分布式应用程序如何相互调用?

  • http(httpurlConnection) 好处:调用简单,使用80端口一般不会被防火墙拦截;短连接,用到时就建立连接,用完了就断开连接;

  • RPC(remote procedure Call 远程方法调用)-tcp 长连接:在进行数据交换时效率会高一些;
    RestTemplate()(基于http协议调用)

  • 服务端应用(spring boot 已经内嵌了tomcat 所以支持对http协议的支持)
    服务器端的开发就是用之前的springmvc技术就可以完成;服务器端只需要提供json数据就可以了;

  • 客户端应用

  1. 使用java原生的api完成客户端的调用
public class Client {
    //将json格式转为对象
    static ObjectMapper om=new ObjectMapper();

    public static void main(String[] args) throws IOException {
        HttpURLConnection conn = (HttpURLConnection)
                new URL("http://192.168.9.2:8080/user").openConnection();
        
        //转换获取到的字节流为字符流
        InputStream in = conn.getInputStream();
        InputStreamReader reader = new InputStreamReader(in);
        BufferedReader r = new BufferedReader(reader);
        
        //输出字符流
        while (true){
            String s = r.readLine();
            if(s==null){
                break;
            }

            User user = om.readValue(s, User.class);
            System.out.println(user);
        }
        r.close();
        conn.disconnect();
    }

}

  1. 使用spring的RestTemplate工具类对刚才的调用进行简化;

加入jar包依赖

    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
    </dependencies>
public class Client2 {

    public static void main(String[] args) {
        RestTemplate template = new RestTemplate();

        User user = template.getForObject("http://192.168.9.2:8080/user", User.class);
        System.out.println(user);
    }
}

Dubbo(RPC 框架)

在这里插入图片描述

provider 服务提供者
consumer 服务消费者
registry 注册中心:可以把提供者发生的一些变更通知给消费者;

  1. 服务提供者启动后,会向注册中心注册提供者信息(ip、服务名、方法定义);
  2. 消费者启动后,向注册中心订阅服务信息;
  3. 一旦服务提供者的信息发生了变更,注册中心负责把这些变更通知给消费者;
  4. 消费者调用服务者的方法是直接调用的,不用通过注册中心;

- 注册中心
第三方的zookeeper(分布式的协调框架),可以把各种服务进行统一的配置放入注册中心;其中会存储服务提供者和服务消费者的相关信息;
5. 下载zookeeper
6. 修改配置文件 conf 将zoo_sample.cfd复制一份改名为zoo.cfg;
7. 进入解压目录bin,执行zkServer.cmd脚本文件;
8. 可以通过一个叫ZooInspector查看注册中心的运行信息;
注册中心提供的端口,下来provider和Consumer都需要连接这个端口;
在这里插入图片描述

- dubbo 控制台
子项目,以springboot开发的可以以图形界面的方式查看dubbo中提供者、消费者的信息;
安装

  1. 下载源代码
    git clone
  2. 编译源代码
    mvn -Dmaven.test.skip=true clean package
    用idea打包
    在这里插入图片描述
    3)运行获得的jar包
    java -jar dubbo-admin-server-0.1.jar --server.port=7070

需要先启动注册中心,再启动控制台;

- 开发dubbo项目

  1. 开发公共api项目
    公共类与接口的定义,UserService、User
    打成jar包
package com.westos.api;

public interface UserService {

    public void insert(User user);

    public void update(User user);

    public User find(String user);
}
  1. 开发privider提供者
    pom.xml中要添加必要的依赖spring-boot,dubbo,zookeeper
    <!-- spring boot 父依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-parent</artifactId>
        <version>2.1.1.RELEASE</version>
    </parent>

    <!-- 常量 设置 spring boot,dubbo 等版本 -->
    <properties>
        <spring-boot.version>2.1.1.RELEASE</spring-boot.version>
        <dubbo.version>2.7.0</dubbo.version>
        <zookeeper.version>3.4.6</zookeeper.version>
        <curator.version>4.1.0</curator.version>
    </properties>

    <!-- 依赖管理,以后可以把这些移入一个 pom 项目,方便进行统一版本控制 -->
    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Apache Dubbo  -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- springboot 与 dubbo 整合 -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>${dubbo.version}</version>
            </dependency>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <!-- 排除 dubbo 引用的 spring,避免与外面指定的 spring 冲突 -->
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>javax.servlet</groupId>
                        <artifactId>servlet-api</artifactId>
                    </exclusion>
                    <!-- 排除 dubbo 使用的 log4j 日志系统,避免和 springboot 默认的 logback 冲突 -->
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

            <!-- dubbo 注册中心依赖,zookeeper -->
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>${zookeeper.version}</version>
                <exclusions>
                    <!-- 排除 zookeeper 使用的 log4j 日志系统,避免和 springboot 默认的 logback 冲突 -->
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

            <!-- dubbo 注册中心依赖, dubbo 官网给出的 curator 的版本和包名是错误的 -->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>${curator.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>${curator.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- spring boot 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- 公共 api -->
        <dependency>
            <groupId>com.westos</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- 用 java.version 不能生效,可能被 dubbo 覆盖了 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

配置

# 配置端口
server.port=8080

# 应用程序的名字, 需要唯一, 不能和注册中心中其他程序冲突
spring.application.name=provider

# 注册中心
dubbo.registry.address=zookeeper://localhost:2181
# 设置连接注册中心的超时时间  3 分钟
dubbo.registry.timeout=180000

# 把元数据信息 发布至注册中心
dubbo.metadata-report.address=zookeeper://localhost:2181

# 指定 导出服务 的包名
dubbo.scan.base-packages=com.westos.provider
package com.westos.provider;

import com.westos.User;
import com.westos.UserService;

import org.apache.dubbo.config.annotation.Service;

@Service
public class UserServiceImpl implements UserService {

    @Override
    public void insert(User user) {
        System.out.println("insert" +user.getName());
    }

    @Override
    public void update(User user) {

    }

    @Override
    public User find(String name, int age, String sex) {
        User user = new User();
        user.setName(name);
        user.setAge(age);
        user.setSex(sex);
        return user;
    }
    
    @Override
    public void delete() {

    }
}

3.开发consume消费者
spring配置

# 端口
server.port=9090

# 给消费者应用起一个唯一的名字
spring.application.name=Msk-consumer

# 注册中心地址
dubbo.registry.address=zookeeper://localhost:2181
dubbo.registry.timeout=180000
package com.westos.controller;
import com.westos.User;
import com.westos.UserService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ClientController {

//    使用公共的api接口把provider和consumer联系起来
    @Reference
    private UserService userService;

    @RequestMapping("/user")
    public User find(){
        return userService.find("李四",19,"男");
    }

}

调用流程

  • 浏览器中访问消费者http://localhost:9090/user
  • 根据此地址找到控制器方法,接下来调用UserService;
  • 但UserService是一个接口,实现不在消费者这边;
  • dubbo 针对这个UserService接口生成一个代理对象
  • 代理对象:
    • 代理对象会访问注册中心,把UserService服务的信息下载到本地;
    • 这些服务信息会缓存至本地,后续的调用不会再依赖注册中心;
    • 底层netty nio 非阻塞io 跟服务器

Rest和Dubbo的优缺点

  • dubbo:应用于同一语言编写的两个应用之间;性能优于rest,基于tcp传输的是字节;服务应用程序之间;更适合长链接;支持服务的治理;
  • rest:任意语言任意平台之间进行调用;基于http传输的是字符;建立短连接;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值