当前位置: 首页 > news >正文

Akka2

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

Akka2 博客分类: java

假设有一个很耗时的运算,单台机器已经没法满足需求,这时你可以想到由多台计算机协作完成。具体怎么做呢。

举个很简单的例子,假设这个耗时的运算是从1加到100000,你现在有两台服务器,可以让这两台服务器分别完成从1加到50000,和从50001加到100000,然后本机完成这两个结果之和。

 

两台服务器分别启动两个akka Server,同时还有一个CalcActor。这个计算actor接收两个参数:Integer start和Integer end,可以从start一直加到end,最后将结果返回给发送者:getSender().tell(result)。

@Log4j
class CalcActor extends UntypedActor {
    @Override
    void onReceive(Object message) {
        log.debug "CalcActor received: ${message}----self:${getSelf()},sender:${getSender()}"
        if (message instanceof String) {
            String[] args = message.split(",")
            int start = Integer.parseInt(args[0])
            int end = Integer.parseInt(args[1])
            double result = 0d
            println("start calc:" + start + " upto " + end)
            start.upto(end) {
                result += it
            }
            sleep(5000) //模拟还要额外耗时5秒
            println("result:" + result)
            getSender().tell(result)
        } else {
            unhandled(message)
        }
    }
}
两个服务器分别为:
AkkaServerApp serverA = new AkkaServerApp("sc", "10.68.3.122", 8888, "calc") //AkkaSystemName为sc,ip为10.68.3.122,端口为8888,serviceName为calc。

    AkkaServerApp serverA = new AkkaServerApp("sp", "10.68.3.124", 8888, "calc")//AkkaSystemName为sp,ip为10.68.3.124,端口为8888,serviceName为calc。

主要的代码在客户端:
public static void main(String[] args) throws Exception {

        final AkkaServerApp app = new AkkaServerApp("xwc", "127.0.0.1", 6666, "client");//客户端akka配置
        ActorRef remoteCalcA1 = app.getSystem().actorOf(new Props(CalcActor.class)..withDeploy(new Deploy(new RemoteScope(new Address("akka", "sc", "10.68.3.122", 8888)))), "clientCalcA1");//将CalcActor发布到远程10.68.3.122上
        ActorRef remoteCalcA2 = app.getSystem().actorOf(new Props(CalcActor.class)..withDeploy(new Deploy(new RemoteScope(new Address("akka", "sc", "10.68.3.122", 8888)))), "clientCalcA2");//将CalcActor发布到远程10.68.3.124上

        final List<Future<Double>> frs = new ArrayList<Future<Double>>();//异步返回结果Future存放在list中
//tell只请求,是否响应它完全不知道。ask是请求,并明确知道未来会相应。        
//        remoteCalcA.tell("1,10000", app.getServerActor());
//        remoteCalcB.tell("10001,20000", app.getServerActor());
        Future f1 = akka.pattern.Patterns.ask(remoteCalcA1, "1,50000", 150000);//让远程122计算从1加到50000,超时时间为150秒
        Future f2 = akka.pattern.Patterns.ask(remoteCalcA1, "50001,100000", 150000);//并发地让远程124计算从50001加到100000,超时时间150秒
        frs.add(f1);
        frs.add(f2);

        Future<Iterable<Double>> future = Futures.sequence(frs, app.getSystem().dispatcher());将未来返回的结果转换成Future<Iterable<Double>>
        Future<Double> fr = future.map(new Mapper<Iterable<Double>, Double>() {

            @Override
            public Double apply(Iterable<Double> parameter) {
                Double result = 0d;
                for (Double s : parameter) {//计算两个服务器返回的结果
                    result += s;
                }
                return result;
            }

        });

        fr.onSuccess(new OnSuccess<Double>() {
            @Override
            public void onSuccess(Double result) {
                System.out.println("云计算返回结果-----" + result);
            }
        });
    }

 

还可以让服务器并发处理:把给从1加到50000的任务分成5个线程并行处理:1..10000,10001..20000,20001..30000,30001..40000,40001..50000,这样能更好地提高效率。

如果按上面的方法仅仅是发布多个remote actor:

ActorRef remoteCalcAn = app.getSystem().actorOf(new Props(CalcActor.class)..withDeploy(new Deploy(new RemoteScope(new Address("akka", "sc", "10.68.3.122", 8888)))), "clientCalcAn");

是没法提高效率的,因为这时的CalcActor是单线程的,它只会先接收1..10000,处理完后再接收10001..20000并处理。。。。。

使其能够并行处理很简单,创建remoteActor时加上withRoute即可:

ActorRef remoteCalcAn = app.getSystem().actorOf(new Props(CalcActor.class).withRouter(new RoundRobinRouter(5)).withDeploy(new Deploy(new RemoteScope(new Address("akka", "sc", "10.68.3.122", 8888)))), "clientCalcAn");  //RoundRobinRouter的参数5可以理解为分配5个线程并行处理


代码跟上面基本相同 

public static void main(String[] args) throws Exception {

        final AkkaServerApp app = new AkkaServerApp("xwc", "127.0.0.1", 6666, "client");
        ActorRef remoteCalcA1 = app.getSystem().actorOf(new Props(CalcActor.class).withRouter(new RoundRobinRouter(4)).withDeploy(new Deploy(new RemoteScope(new Address("akka", "sc", "10.68.3.122", 8888)))), "clientCalcA1");    
        ActorRef remoteCalcB1 = app.getSystem().actorOf(new Props(CalcActor.class).withRouter(new RoundRobinRouter(4)).withDeploy(new Deploy(new RemoteScope(new Address("akka", "sp", "10.68.3.124", 8888)))), "clientCalcB1");
   
        final List<Future<Double>> frs = new ArrayList<Future<Double>>();
        
        Future f1 = akka.pattern.Patterns.ask(remoteCalcA1, "1,10000", 150000);
        Future f2 = akka.pattern.Patterns.ask(remoteCalcA1, "10001,20000", 150000);
        Future f3 = akka.pattern.Patterns.ask(remoteCalcA1, "20001,30000", 150000);
        Future f4 = akka.pattern.Patterns.ask(remoteCalcA1, "30001,40000", 150000);
        Future f5 = akka.pattern.Patterns.ask(remoteCalcB1, "40001,50000", 150000);
        Future f6 = akka.pattern.Patterns.ask(remoteCalcB1, "50001,60000", 150000);
        Future f7 = akka.pattern.Patterns.ask(remoteCalcB1, "60001,70000", 150000);
        Future f8 = akka.pattern.Patterns.ask(remoteCalcB1, "70001,80000", 150000);
        frs.add(f1);
        frs.add(f2);
        frs.add(f3);
        frs.add(f4);
        frs.add(f5);
        frs.add(f6);
        frs.add(f7);
        frs.add(f8);

        Future<Iterable<Double>> future = Futures.sequence(frs, app.getSystem().dispatcher());
        Future<Double> fr = future.map(new Mapper<Iterable<Double>, Double>() {

            @Override
            public Double apply(Iterable<Double> parameter) {
                Double result = 0d;
                for (Double s : parameter) {
                    result += s;
                }
                return result;
            }

        });

        fr.onSuccess(new OnSuccess<Double>() {
            @Override
            public void onSuccess(Double result) {
                System.out.println("云计算返回从1加到80000的结果-----" + result);
            }
        });
    }


http://m.oschina.net/blog/81118

转载于:https://my.oschina.net/xiaominmin/blog/1597722

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • neo4j入门开发,以及在sns关系中的应用
  • Redis 替代品SSDB Java客户端
  • 获取URL地址中的GET参数
  • hadoop yarn 配置
  • android文件关联之mime type
  • 两年前端职业生涯总结
  • 云数据库Memcache版使用教程
  • 8.2. GUI
  • alertmanager源码阅读 - dispatcher
  • java8-模拟hadoop
  • 第 13 章 Barman for PostgreSQL
  • spark 源码编译 standalone 模式部署
  • 在华为设备上实施GRE隧道和IPSEC ***
  • 如何在数据库动态建表
  • 十年阿里java架构师的六大设计原则和项目经验
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • angular学习第一篇-----环境搭建
  • classpath对获取配置文件的影响
  • ERLANG 网工修炼笔记 ---- UDP
  • Fabric架构演变之路
  • httpie使用详解
  • JavaWeb(学习笔记二)
  • java第三方包学习之lombok
  • java中的hashCode
  • Just for fun——迅速写完快速排序
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • Yii源码解读-服务定位器(Service Locator)
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 前端性能优化——回流与重绘
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 翻译 | The Principles of OOD 面向对象设计原则
  • # Apache SeaTunnel 究竟是什么?
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (规划)24届春招和25届暑假实习路线准备规划
  • (理论篇)httpmoudle和httphandler一览
  • (南京观海微电子)——示波器使用介绍
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (四)Controller接口控制器详解(三)
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (一)Neo4j下载安装以及初次使用
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (转载)OpenStack Hacker养成指南
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .htaccess配置重写url引擎