HarmonyOS开发实例:【分布式邮件】

这篇具有很好参考价值的文章主要介绍了HarmonyOS开发实例:【分布式邮件】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

基于TS扩展的声明式开发范式编程语言编写的一个分布式邮件系统,可以由一台设备拉起另一台设备,每次改动邮件内容,都会同步更新两台设备的信息。效果图如下:

HarmonyOS开发实例:【分布式邮件】,鸿蒙开发,harmonyos,分布式,typescript,openharmony,鸿蒙开发,鸿蒙,移动开发

HarmonyOS开发实例:【分布式邮件】,鸿蒙开发,harmonyos,分布式,typescript,openharmony,鸿蒙开发,鸿蒙,移动开发

搭建OpenHarmony开发环境

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以Hi3516DV300开发板为例,参照以下步骤进行:

  1. [获取OpenHarmony系统版本]:标准系统解决方案(二进制)。

    以3.0版本为例:

    HarmonyOS开发实例:【分布式邮件】,鸿蒙开发,harmonyos,分布式,typescript,openharmony,鸿蒙开发,鸿蒙,移动开发

  2. 搭建烧录环境。

    1. [完成DevEco Device Tool的安装]
    2. [完成Hi3516开发板的烧录]
    3. 鸿蒙开发指导:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击复制转到打开。
  3. 搭建开发环境。

    1. 开始前请参考[工具准备],完成DevEco Studio的安装和开发环境配置。
    2. 开发环境配置完成后,请参考[使用工程向导]创建工程(模板选择“Empty Ability”),选择JS或者eTS语言开发。
    3. 工程创建完成后,选择使用[真机进行调测]。
      2.鸿蒙HarmonyOS与OpenHarmony技术知识籽料+mau123789是v直接拿

HarmonyOS开发实例:【分布式邮件】,鸿蒙开发,harmonyos,分布式,typescript,openharmony,鸿蒙开发,鸿蒙,移动开发

分布式组网

本章节以系统自带的音乐播放器为例,介绍如何完成两台设备的分布式组网。

  1. 硬件准备:准备两台烧录相同的版本系统的Hi3516DV300开发板A、B、一根网线及TYPE-C转USB线。

  2. 保证开发板A、B上电开机状态,网线两端分别连接开发板A、B的网口,将TYPE-C转USB线先连接A,使用hdc_std.exe,在命令行输入hdc_std shell ifconfig eth0 192.168.3.125,设置成功后,将TYPE-C转USB线连接B,在命令行输入hdc_std shell ifconfig eth0 192.168.3.126即可。

  3. 将设备A,B设置为互相信任的设备。

    • 找到系统应用“音乐”。
    • 设备A打开音乐,点击左下角流转按钮,弹出列表框,在列表中会展示远端设备的id。

      HarmonyOS开发实例:【分布式邮件】,鸿蒙开发,harmonyos,分布式,typescript,openharmony,鸿蒙开发,鸿蒙,移动开发

    • 选择远端设备B的id,另一台开发板(设备B)会弹出验证的选项框。

      HarmonyOS开发实例:【分布式邮件】,鸿蒙开发,harmonyos,分布式,typescript,openharmony,鸿蒙开发,鸿蒙,移动开发

    • 设备B点击允许,设备B将会弹出随机PIN码,将设备B的PIN码输入到设备A的PIN码填入框中。

    HarmonyOS开发实例:【分布式邮件】,鸿蒙开发,harmonyos,分布式,typescript,openharmony,鸿蒙开发,鸿蒙,移动开发HarmonyOS开发实例:【分布式邮件】,鸿蒙开发,harmonyos,分布式,typescript,openharmony,鸿蒙开发,鸿蒙,移动开发

    配网完毕。

代码结构解读

本篇Codelab只对核心代码进行讲解,首先来介绍下整个工程的代码结构:

HarmonyOS开发实例:【分布式邮件】,鸿蒙开发,harmonyos,分布式,typescript,openharmony,鸿蒙开发,鸿蒙,移动开发

  • MainAbility:存放应用主页面。

    • pages/index.ets:应用主页面。
  • model:存放获取组网内的设备列表相关文件。

    • RemoteDeviceModel.ets:获取组网内的设备列表。
  • ServiceAbility:存放ServiceAbility相关文件。

    • service.ts:service服务,用于跨设备连接后通讯。
  • resources :存放工程使用到的资源文件。

    • resources/rawfile:存放工程中使用的图片资源文件。
  • config.json:配置文件。

实现页面布局和样式

在本章节中,您将学会如何制作一个简单的邮件界面。

  1. 实现主页面布局和样式。

    • 在MainAbility/pages/index.ets 主界面文件中布局整个邮件页面,包括收件人、发件人、主题、内容等等,代码如下:

      @Entry
      @Component
      struct Index {
        private imageList: any[]= []
        @Provide dataList: string[]= ['xiaohua@128.com','xiaoming@128.com','假期温馨提示','2022年新春佳节即将来临,请同学们细读节前相关温馨提示,保持办公场所环境整洁,假期期间注意信息及个人安全,预祝全体同学新春快乐,虎虎生威!']
      
        dialogController: CustomDialogController = new CustomDialogController({
          builder: CustomDialogExample({ cancel: this.onCancel, confirm: this.onAccept }),
          cancel: this.existApp,
          autoCancel: true
        })
      
        build() {
          Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween }) {
            Column() {
              Row() {
                Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
                  Text('✕').fontSize(20).fontColor('#000000')
                  Button('发送').width(70).fontSize(14).fontColor('#ffffff').backgroundColor('#fc4646')
                    .onClick(() => {
                      RegisterDeviceListCallback();
                      this.dialogController.open();
                    })
                }
                .height(50)
                .padding({ top: 10, right: 15, bottom: 10, left: 15 })
              }
      
              Column() {
                Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
                  Text('收件人').width(70).height(30).fontSize(15).fontColor('#969393')
                  Text(this.dataList[0]).width('100%').height(30).fontSize(15).fontColor('#000000')
                }
                .padding({ top: 5, right: 15, bottom: 5, left: 15 })
      
                Text().width('100%').height(1).backgroundColor('#f8f6f6')
      
                Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
                  Text('发件人').width(70).height(30).fontSize(15).fontColor('#969393')
                  Text(this.dataList[1]).width('100%').height(30).fontSize(15).fontColor('#000000')
                }
                .padding({ top: 5, right: 15, bottom: 5, left: 15 })
      
                Text().width('100%').height(1).backgroundColor('#f8f6f6')
      
                Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
                  Text('主题').width(50).height(30).fontSize(15).fontColor('#969393')
                  Text(this.dataList[2]).width('100%').height(30).fontSize(15).fontColor('#000000')
                }
                .padding({ top: 5, right: 15, bottom: 5, left: 15 })
      
                Text().width('100%').height(1).backgroundColor('#f8f6f6')
                TextArea({ placeholder: 'input your word', text: this.dataList[3]}).height('100%').width('100%')
                  .onChange((value: string) => {
                    this.dataList[3] = value
                    if(mRemote){
                      sendMessageToRemoteService(JSON.stringify(this.dataList));
                    }
                      onDisconnectService();
                })
              }
            }
      
            Column() {
              Flex({ direction: FlexDirection.Row }) {
                List() {
                  ForEach(this.imageList, (item) => {
                    ListItem() {
                      Image(item).width(50).height(50).objectFit(ImageFit.Contain)
                    }.editable(true)
                  }, item => item)
                }
                .listDirection(Axis.Horizontal) // 排列方向
                .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
              }.width('100%').height(50).backgroundColor('#ccc')
      
              Text().width('100%').height(1).backgroundColor('#f8f6f6')
              Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
                Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
                  Button({ stateEffect: false }) {
                    Image($rawfile('icon_photo.png')).width(20).height(20)
                  }.backgroundColor('#ffffff').margin({ right: 20 })
                  .onClick(() => {
                    RegisterDeviceListCallback();
                    this.dialogController.open();
                  })
      
                  Button({ stateEffect: false }) {
                    Image($rawfile('icon_at.png')).width(20).height(20)
                  }.backgroundColor('#ffffff')
                }
      
                Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.End }) {
                  Button({ stateEffect: false }) {
                    Image($rawfile('icon_distributed.png')).width(20).height(20)
                  }.backgroundColor('#ffffff')
                  .onClick(() => {
                     this.getDeviceList()
                  })
      
                  Button({ stateEffect: false }) {
                    Image($rawfile('icon_timer.png')).width(20).height(20)
                  }.backgroundColor('#ffffff').margin({ left: 10, right: 10 })
      
                  Button({ stateEffect: false }) {
                    Image($rawfile('icon_enclosure.png')).width(20).height(20)
                  }.backgroundColor('#ffffff')
                }
              }.height(50).padding(15)
            }
          }.width('100%').padding({ top: 5, bottom: 15 })
        }
      }
      

      在入口组件的生命周期函数aboutToAppear()中调用订阅事件。如果Ability是被其他设备拉起的,在aboutToAppear()中调用featureAbility.getWant(),可通过want中的参数重新初始化dataList数组,入口组件的生命周期函数aboutToAppear()代码如下:

      async aboutToAppear() {
          this.subscribeEvent();
          let self = this;
          // 当被拉起时,通过want传递的参数同步对端界面UI
          await featureAbility.getWant((error, want) => {
            var status = want.parameters;
            if (want.parameters.dataList) {
              self.dataList = JSON.parse(status.dataList)
              // 远端被拉起后,连接对端的service
              if (want.parameters.remoteDeviceId) {
                let remoteDeviceId = want.parameters.remoteDeviceId
                onConnectRemoteService(remoteDeviceId)
              }
            }
          });
        }
      
  2. 给"发送"按钮添加点击事件。

    点击"发送"按钮,调用拉起弹窗函数,弹窗中显示可拉起的同局域网下的设备,代码如下:

    Button('发送').width(70).fontSize(14).fontColor('#ffffff').backgroundColor('#fc4646')
          .onClick(() => {
            RegisterDeviceListCallback();
            this.dialogController.open();
          })
    
  3. 给内容区域Textarea添加onChange事件。

    内容区域文字变化会调用onChange()方法,每一次的变化都会调用sendMessageToRemoteService()方法去同步另一个设备的数据。其中onChange()和sendMessageToRemoteService()方法代码如下:

    TextArea({ placeholder: 'input your word', text: this.dataList[3]}).height('100%').width('100%')
        .onChange((value: string) => {
          this.dataList[3] = value
          if(mRemote){
            sendMessageToRemoteService(JSON.stringify(this.dataList));
          }
          onDisconnectService();
      })
    
      async function sendMessageToRemoteService(dataList) {
      if (mRemote == null) {
        prompt.showToast({
          message: "mRemote is null"
        });
        return;
      }
      let option = new rpc.MessageOption();
      let data = new rpc.MessageParcel();
      let reply = new rpc.MessageParcel();
      data.writeStringArray(JSON.parse(dataList));
      prompt.showToast({
        message: "sendMessageToRemoteService" + dataList,
        duration: 3000
      });
    
      await mRemote.sendRequest(1, data, reply, option);
      let msg = reply.readInt();
    
    }
    

拉起远端FA及连接远端Service服务

在本章节中,您将学会如何拉起在同一组网内的设备上的FA,并且连接远端Service服务。

  1. 调用featureAbility.startAbility()方法,拉起远端FA,并同步界面UI。

    点击"分布式拉起"按钮,调用RegisterDeviceListCallback()发现设备列表,并弹出设备列表选择框CustomDialogExample,选择设备后拉起远端FA。CustomDialogExample()代码如下:

    // 设备列表弹出框
    @CustomDialog
    struct CustomDialogExample {
      @State editFlag: boolean = false
      @Consume imageIndexForPosition : number[]
      @Consume pictureList: string[]
      controller: CustomDialogController
      cancel: () => void
      confirm: () => void
      build() {
        Column() {
          List({ space: 10, initialIndex: 0 }) {
            ForEach(DeviceIdList, (item) => {
              ListItem() {
                Row() {
                  Text(item)
                    .width('87%').height(50).fontSize(10)
                    .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
                    .onClick(() => {
                      onStartRemoteAbility(item,this.imageIndexForPosition,this.pictureList);
                      this.controller.close();
                    })
                  Radio({value:item})
                    .onChange((isChecked) => {
                      onStartRemoteAbility(item,this.imageIndexForPosition,this.pictureList);
                      this.controller.close();
                    }).checked(false)
                }
              }.editable(this.editFlag)
            }, item => item)
          }
        }.width('100%').height(200).backgroundColor(0xDCDCDC).padding({ top: 5 })
      }
    }
    

    点击Text组件或者Radio组件都会调用onStartRemoteAbility()方法拉起远端FA,onStartRemoteAbility()代码如下:

    function onStartRemoteAbility(deviceId,imageIndexForPosition,pictureList: string[]) {
      AuthDevice(deviceId);
      let numDevices = remoteDeviceModel.deviceList.length;
      if (numDevices === 0) {
        prompt.showToast({
          message: "onStartRemoteAbility no device found"
        });
        return;
      }
    
      var params = {
        imageIndexForPosition: JSON.stringify(imageIndexForPosition),
        pictureList : JSON.stringify(pictureList),
        remoteDeviceId : localDeviceId
      }
      var wantValue = {
        bundleName: 'com.huawei.cookbook',
        abilityName: 'com.example.openharmonypicturegame.MainAbility',
        deviceId: deviceId,
        parameters: params
      };
      featureAbility.startAbility({
        want: wantValue
      }).then((data) => {
        // 拉起远端后,连接远端service
        onConnectRemoteService(deviceId)
      });
    }
    
  2. 调用featureAbility.connectAbility方法,连接远端Service服务,连接成功后返回remote对象。

    在featureAbility.startAbility()成功的回调中调用onConnectRemoteService()方法,onConnectRemoteService()方法代码如下:

    // 连接远端Service
    async function onConnectRemoteService(deviceId) {
      // 连接成功的回调
      async function onConnectCallback(element, remote) {
         mRemote = remote;
      }
      // Service异常死亡的回调
      function onDisconnectCallback(element) {
      }
      // 连接失败的回调
      function onFailedCallback(code) {
        prompt.showToast({
          message: "onConnectRemoteService onFailed: " + code
        });
      }
      let numDevices = remoteDeviceModel.deviceList.length;
      if (numDevices === 0) {
        prompt.showToast({
          message: "onConnectRemoteService no device found"
        });
        return;
      }
      connectedAbility = await featureAbility.connectAbility(
        {
          deviceId: deviceId,
          bundleName: "com.huawei.cookbook",
          abilityName: "com.example.openharmonypicturegame.ServiceAbility",
        },
        {
          onConnect: onConnectCallback,
          onDisconnect: onDisconnectCallback,
          onFailed: onFailedCallback,
        },
      );
    }
    

    在配置文件config.json需要设置ServiceAbility的属性visible为true,代码如下:

    "abilities": [
          ...
          {
            "visible": true,
            "srcPath": "ServiceAbility",
            "name": ".ServiceAbility",
            "icon": "$media:icon",
            "srcLanguage": "ets",
            "description": "$string:description_serviceability",
            "type": "service"
          }
    ],
    

    同时,Service侧也需要在onConnect()时返回IRemoteObject,从而定义与Service进行通信的接口。onConnect()需要返回一个IRemoteObject对象,OpenHarmony提供了IRemoteObject的默认实现,通过继承rpc.RemoteObject来创建自定义的实现类。

    Service侧把自身的实例返回给调用侧的代码如下:

    import rpc from "@ohos.rpc";
    import commonEvent from '@ohos.commonEvent';
    class FirstServiceAbilityStub extends rpc.RemoteObject{
        constructor(des) {
            if (typeof des === 'string') {
                super(des);
            } else {
                return null;
            }
        }
        onRemoteRequest(code, data, reply, option) {
            if (code === 1) {
                let arr = data.readIntArray();
                reply.writeInt(100);
                // 发布公共事件相关流程
    	    ...
    
    
            } else {
            }
            return true;
        }
    }
    
    export default {
        // 创建Service的时候调用,用于Service的初始化
        onStart() {
        },
        // 在Service销毁时调用。Service应通过实现此方法来清理任何资源,如关闭线程、注册的侦听器等。
        onStop() {
        },
        // 在Ability和Service连接时调用,该方法返回IRemoteObject对象,开发者可以在该回调函数中生成对应Service的IPC通信通道
        onConnect(want) {
            try {
                let value = JSON.stringify(want);
            } catch(error) {
            }
            return new FirstServiceAbilityStub("[pictureGame] first ts service stub");
        },
        // 在Ability与绑定的Service断开连接时调用
        onDisconnect(want) {
            let value = JSON.stringify(want);
        },
        // 在Service创建完成之后调用,该方法在客户端每次启动该Service时都会调用
        onCommand(want, startId) {
            let value = JSON.stringify(want);
        }
    };
    

RPC跨设备通讯

在本章节中,您将学会在成功连接远端Service服务的前提下,如何利用RPC进行跨设备通讯。

  1. 成功连接远端Service服务的前提下,在正文部分增删文字,都会完成一次跨设备通讯,假如在设备A端输入文字,消息的传递是由设备A端的FA传递到设备B的Service服务,发送消息的方法sendMessageToRemoteService()代码如下:

    // 连接成功后发送消息
    async function sendMessageToRemoteService(imageIndexForPosition) {
      if (mRemote == null) {
        prompt.showToast({
          message: "mRemote is null"
        });
        return;
      }
      let option = new rpc.MessageOption();
      let data = new rpc.MessageParcel();
      let reply = new rpc.MessageParcel();
      data.writeIntArray(JSON.parse(imageIndexForPosition));
      await mRemote.sendRequest(1, data, reply, option);
      let msg = reply.readInt();
    }
    
  2. 在B端的Service接收消息,当A端成功连接B端Service服务后,在A端会返回一个remote对象,当A端remote对象调用sendRequest()方法后,在B端的Service中的onRemoteRequest()方法中会接收到发送的消息,其中继承rpc.RemoteObject的类和onRemoteRequest()方法代码如下:

    class FirstServiceAbilityStub extends rpc.RemoteObject{
        constructor(des) {
            if (typeof des === 'string') {
                super(des);
            } else {
                return null;
            }
        }
    
        onRemoteRequest(code, data, reply, option) {
            if (code === 1) {
                // 从data中接收数据
                let arr = data.readIntArray();
                // 回复接收成功标识
                reply.writeInt(100);
                // 发布公共事件相关流程
               ...
    
            } else {
            }
            return true;
        }
    }
    

FA订阅公共事件

在九宫格组件PictureGrid的生命周期函数aboutToAppear()中,调用订阅公共事件方法subscribeEvent(),用来订阅"publish_moveImage"公共事件,subscribeEvent()代码如下:

 subscribeEvent(){
    let self = this;
    // 用于保存创建成功的订阅者对象,后续使用其完成订阅及退订的动作
    var subscriber; 
    // 订阅者信息
    var subscribeInfo = {
      events: ["publish_moveImage"],
      priority: 100

    };

    // 设置有序公共事件的结果代码回调
    function SetCodeCallBack(err) {
    }
    // 设置有序公共事件的结果数据回调
    function SetDataCallBack(err) {
    }
    // 完成本次有序公共事件处理回调
    function FinishCommonEventCallBack(err) {
    }
    // 订阅公共事件回调
    function SubscribeCallBack(err, data) {
      let msgData = data.data;
      let code = data.code;
      // 设置有序公共事件的结果代码
      subscriber.setCode(code, SetCodeCallBack);
      // 设置有序公共事件的结果数据
      subscriber.setData(msgData, SetDataCallBack);
      // 完成本次有序公共事件处理
      subscriber.finishCommonEvent(FinishCommonEventCallBack)
      // 处理接收到的数据data
      self.imageIndexForPosition = data.parameters.imageIndexForPosition;
      self.pictureList = [];
      self.imageIndexForPosition.forEach(value => {
        if (value == 9) {
          self.pictureList.push("--")
        } else {
          self.pictureList.push(`picture_0` + value + `.png`)
        }
      });

      self.onFinish();
    }

    // 创建订阅者回调
    function CreateSubscriberCallBack(err, data) {
      subscriber = data;
      // 订阅公共事件
      commonEvent.subscribe(subscriber, SubscribeCallBack);
    }

    // 创建订阅者
    commonEvent.createSubscriber(subscribeInfo, CreateSubscriberCallBack);
 }

在FA中订阅到Service服务发布的"publish_moveImage"事件后,在SubscribeCallBack()回调中重新赋值imageIndexForPosition数组与pictureList数组,从而同步更新界面UI。

service发布公共事件

当Service服务接收到消息后,在onRemoteRequest()发布公共事件,代码如下:

onRemoteRequest(code, data, reply, option) {
    if (code === 1) {
	// 从data中接收数据
	let arr = data.readIntArray();
	// 回复接收成功标识
	reply.writeInt(100);
	// 公共事件相关信息
	var params ={
	    imageIndexForPosition: arr
	}
	var options = {
            // 公共事件的初始代码
	    code: 1,
            // 公共事件的初始数据			
	    data: 'init data',、
            // 有序公共事件 	        
	    isOrdered: true, 	
	    bundleName: 'com.huawei.cookbook',
	    parameters: params

        }
	// 发布公共事件回调
	function PublishCallBack() {
	}
	// 发布公共事件
	commonEvent.publish("publish_moveImage", options, PublishCallBack);

	} else {
	}
	return true;
 }

在接收到消息后,把接收到的图片位置数组放入params中,然后发布名称为"publish_moveImage"的有序公共事件。文章来源地址https://www.toymoban.com/news/detail-860413.html

到了这里,关于HarmonyOS开发实例:【分布式邮件】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《HarmonyOS开发 – OpenHarmony开发笔记(基于小型系统)》第4章 OpenHarmony应用开发实例

    开发环境 : 开发系统:Ubuntu 20.04 开发板:Pegasus物联网开发板 MCU:Hi3861 OpenHarmony版本:3.0.1-LTS 1.新建工程及源码 新建目录 在applications/sample/myapp中新建src目录以及myapp.c文件,代码如下所示。 新建编译组织文件 新建applications/sample/myapp/BUILD.gn文件,内容如下所示: static_libr

    2024年02月09日
    浏览(77)
  • HarmonyOS鸿蒙开发指南:基于ArkTS的声明式开发范式 声明式UI开发实例 绘图与动画

    目录 绘制图形 绘制基本几何图形 绘制自定义几何图形 animateTo实现闪屏动画 页面转场动画 绘制能力主要是通过框架提供的绘制组件来支撑,支持svg标准绘制命令。 本节主要学习如何使用绘制组件,绘制详情页食物成分标签(基本几何图形)和应用Logo(自定义图形)。

    2024年01月17日
    浏览(61)
  • HarmonyOS鸿蒙开发指南:UI开发 基于ArkTS的声明式开发范式 声明式UI开发实例 页面布局与连接

    目录 构建食物数据模型 构建食物列表List布局 构建食物分类Grid布局  页面跳转与数据传递

    2024年02月03日
    浏览(55)
  • Zabbix分布式监控系统概述、部署、自定义监控项、邮件告警

    目录 前言 (一)业务架构 (二)运维架构 一、Zabbix分布式监控平台 (一)Zabbix概述 (二)Zabbix监控原理 (三)Zabbix 6.0 新特性 1. Zabbix server高可用 2. Zabbix 6.0 LTS新增Kubernetes监控功能 (四)Zabbix 6.0 功能组件 1.Zabbix Server (1)Zabbix datdbdse (2)Zabbix web 2. Zabbix Agent (1)主动

    2024年01月21日
    浏览(47)
  • 分布式系统概念和设计——Mach实例研究

    Mach实例研究 Mach主要抽象概述 任务 一个Mach任务是一个执行环境 主要包括一个被保护的地址空间和一个内存管理的权能集合 这些权能主要用于访问端口 线程 任务可以包含多个线程 在共享内存的多处理器中,属于同一个任务的线程可以在不同的处理器上并行执行 端口 在Ma

    2024年02月09日
    浏览(39)
  • 机器学习分布式框架ray运行xgboost实例

            Ray是一个开源的分布式计算框架,专门用于构建高性能的机器学习和深度学习应用程序。它的目标是简化分布式计算的复杂性,使得用户能够轻松地将任务并行化并在多台机器上运行,以加速训练和推理的速度。Ray的主要特点包括支持分布式任务执行、Actor模型、

    2024年02月15日
    浏览(44)
  • 机器学习分布式框架ray运行TensorFlow实例

    使用Ray来实现TensorFlow的训练是一种并行化和分布式的方法,它可以有效地加速大规模数据集上的深度学习模型的训练过程。Ray是一个高性能、分布式计算框架,可以在集群上进行任务并行化和数据并行化,从而提高训练速度和可扩展性。 以下是实现TensorFlow训练的概括性描述

    2024年02月15日
    浏览(51)
  • 【Redisson】分布式锁源码分析如何实现多个应用实例互斥

    lockName就是保存到Redis里面的key 直接进行构建方法里面的 super(commandExecutor, name); org.redisson.connection.ServiceManager : private final String id = UUID.randomUUID().toString(); 这个 id 就是 UUID : this.id = getServiceManager().getId(); 这个entryName通过UUID可以区分是哪个应用实例 entryName+threadId可以区分哪个应

    2024年02月11日
    浏览(40)
  • Linux分布式应用 Zabbix监控配置[添加主机 自定义监控内容 邮件报警 自动发现/注册 代理服务器 高可用集群]

    关闭防火墙  服务端和客户端都配置时间同步 服务端和客户端都设置 hosts 解析 设置 zabbix 的下载源,安装 zabbix-agent2 修改 agent2 配置文件 启动 zabbix-agent2 在服务端验证 zabbix-agent2 的连通性 在 Web 页面中添加 agent 主 机 点击左边菜单栏【配置】中的【主机】,点击【创建主机

    2024年02月13日
    浏览(57)
  • Linux分布式应用 Zabbix监控软件实例:监控NGINX的性能

        测试 访问设置的网站 获取NGINX状态统计 过滤结果获取需要的值     服务器端验证     ​​​创建模板 点击左边菜单栏【配置】中的【模板】,点击【创建模板】 【模板名称】设置成 Template NGINX Status 【可见的名称】设置成 Template NGINX Status 【群组】选择 Template 【描述

    2024年02月15日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包