py脚本解决ArcGIS Server服务内存过大的问题

在一台服务器上,使用ArcGIS Server发布地图服务,但是地图服务较多,在发布之后,服务器的内存持续处在95%上下的高位状态,导致服务器运行状态不稳定,经常需要重新启动。重新启动后重新进入这种内存高位的陷阱。

1. 现象

打开任务管理器发现大量ArcSOC.exe进程,这些进程CPU使用率不高,但基本都在50-90m之间,直接占用绝大部分的内存资源。

2. 解决方法

我们打开ArcMap,从右侧ArcCatlog中找到发布的ArcGIS Server服务名称,然后右键选择“服务属性”,如下图所示:

在这里插入图片描述

在弹出的服务编辑器中,选择“池化”,将每台机器的最小实例数修改成0,如下图所示:

在这里插入图片描述

重启服务即可

在这里插入图片描述

3. 在浏览器中打开

在这里插入图片描述

4. 代码批量修改

从2、3中我们可以看到,无非就是修改这些属性,通过接口的调用,动态修改。以下为python代码,以下代码使用的python3.

4.1. 代码内容

# Demonstrates how to modify the min and max instances for a service
# For Http calls
import http.client, urllib, json,requests
# For system tools
import sys
# For reading passwords without echoing
import getpass# Defines the entry point into the script
def main(argv=None):# Print some infoprintprint("This tool is a sample script that resets the minimum and maximum instances allowed for a service.")printserverName ="127.0.01" #raw_input("Enter Server name: ")serverPort = 6080username ="arcgis" #raw_input("Enter user name: ")password ="arcgis" #getpass.getpass("Enter password: ")minInstances =0 #raw_input("Enter the new minimum: ")maxInstances =2 #raw_input("Enter the new maximum: ")# Check to make sure the minimum and maximum are numericaltry:minInstancesNum = int(minInstances)maxInstancesNum = int(maxInstances)except ValueError:print("Numerical value not entered for minimum, maximum, or both.")return# Check to make sure that the minimum is not greater than the maximumif minInstancesNum > maxInstancesNum:print("Maximum number of instances must be greater or equal to minimum number.")return# Get a tokentoken = getToken(username, password, serverName, serverPort)if token == "":print("Could not generate a token with the username and password provided.")returnservice_names=getAllServer(token)for index, service in enumerate(service_names):print(f"{index}/{len(service_names)}:开始修改服务{service}...")AlterServerPerNode(serverName, serverPort,token,service,minInstancesNum,maxInstancesNum)print(f"服务{service}修改完成")# A function to generate a token given username, password and the adminURL.
def getToken(username, password, serverName, serverPort):# Token URL is typically http://server[:port]/arcgis/admin/generateTokentokenURL = "/arcgis/tokens/generateToken"params = urllib.parse.urlencode({'username': username, 'password': password, 'client': 'requestip', 'f': 'json'})headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}# Connect to URL and post parametershttpConn = http.client.HTTPConnection(serverName, serverPort)httpConn.request("POST", tokenURL, params, headers)# Read responseresponse = httpConn.getresponse()if (response.status != 200):httpConn.close()print("Error while fetching tokens from admin URL. Please check the URL and try again.")returnelse:data = response.read()httpConn.close()# Check that data returned is not an error objectif not assertJsonSuccess(data):            return# Extract the token from ittoken = json.loads(data)        return token['token']            def getAllServer(serverName, serverPort,token):service_names = []service_base_url = f"{serverName}:{serverPort}/arcgis/admin/services"# This request only needs the token and the response formatting parameterparams = urllib.parse.urlencode({'token': token, 'f': 'json'})serviceURL=service_base_url+"?"+paramsresponse=requests.get(serviceURL)# httpConn.request("Post", serviceURL, params, headers)# Read responseif (response.status_code  == 200):#data = response.json()data = json.loads(response.text)if "folders" in data:for folder in data["folders"]:service_base_folder_url =f"{service_base_url}/{folder}"folder_url = service_base_folder_url+"?"+params# folder_url = urllib.parse.quote(folder_url, safe='/:')folder_response = requests.get(folder_url)folder_data = json.loads(folder_response.text)for service in folder_data["services"]:if(service["type"]=="MapServer"):service_names.append(f"{folder}/{service['serviceName']}")# if "folders" in data:for service in data["services"]:if(service["type"]=="MapServer"):service_names.append(service['serviceName'])return service_namesdef AlterServerPerNode(serverName, serverPort,token,service,minInstancesNum,maxInstancesNum):service=service+".MapServer"serviceURL = urllib.parse.quote("/arcgis/admin/services/" + service, safe='/:')# This request only needs the token and the response formatting parameterparams = urllib.parse.urlencode({'token': token, 'f': 'json'})headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}# Connect to service to get its current JSON definition    httpConn = http.client.HTTPConnection(serverName, serverPort)httpConn.request("POST", serviceURL, params, headers)# Read responseresponse = httpConn.getresponse()if (response.status != 200):httpConn.close()print("Could not read service information.")returnelse:data = response.read()# Check that data returned is not an error objectif not assertJsonSuccess(data):          print("Error when reading service information. " + str(data))else:print("Service information read successfully. Now changing properties...")# Deserialize response into Python objectdataObj = json.loads(data)if dataObj["minInstancesPerNode"]!=minInstancesNum or dataObj["maxInstancesPerNode"] != maxInstancesNum:# Edit desired properties of the servicedataObj["minInstancesPerNode"] = minInstancesNumdataObj["maxInstancesPerNode"] = maxInstancesNum# Serialize back into JSONupdatedSvcJson = json.dumps(dataObj)# Call the edit operation on the service. Pass in modified JSON.editSvcURL = urllib.parse.quote("/arcgis/admin/services/" + service + "/edit", safe='/:')params = urllib.parse.urlencode({'token': token, 'f': 'json', 'service': updatedSvcJson})httpConn.request("POST", editSvcURL, params, headers)# Read service edit responseeditResponse = httpConn.getresponse()if (editResponse.status != 200):httpConn.close()print("Error while executing edit.")returnelse:editData = editResponse.read()# Check that data returned is not an error objectif not assertJsonSuccess(editData):print("Error returned while editing service" + str(editData))      else:print("Service edited successfully.")httpConn.close()  return# A function that checks that the input JSON object
#  is not an error object.
def assertJsonSuccess(data):obj = json.loads(data)if 'status' in obj and obj['status'] == "error":print("Error: JSON object returns an error. " + str(obj))return Falseelse:return True# Script start
if __name__ == "__main__":sys.exit(main(sys.argv[1:]))

4.2. 代码解读

  1. 导入模块:

    • http.clienturllibjsonrequests:用于处理 HTTP 请求和 JSON 数据的模块。
    • sys:用于处理命令行参数和退出脚本的模块。
    • getpass:用于安全地输入密码而不回显的模块。
  2. 定义 main 函数:

    • main 函数是脚本的入口点,它负责执行主要的操作。
    • 打印一些信息,包括脚本的描述。
    • 获取服务器名称、端口、用户名、密码、最小实例数和最大实例数等输入参数。
    • 检查输入参数的有效性,并确保最小实例数不大于最大实例数。
    • 获取令牌(Token):调用 getToken 函数,使用提供的用户名和密码获取 ArcGIS Server 的令牌。令牌用于身份验证。
    • 获取所有服务列表:调用 getAllServer 函数,获取 ArcGIS Server 上所有的服务名称。
  3. 定义 getToken 函数:

    • getToken 函数用于获取 ArcGIS Server 的令牌(Token),以便进行身份验证。
    • 构建令牌请求的 URL 和参数。
    • 发送 HTTP POST 请求以获取令牌。
    • 解析响应并提取令牌。
  4. 定义 getAllServer 函数:

    • getAllServer 函数用于获取 ArcGIS Server 上的所有服务的名称。
    • 构建服务列表请求的 URL 和参数。
    • 发送 HTTP GET 请求以获取服务列表。
    • 解析响应并提取服务名称,存储在 service_names 列表中。
  5. 定义 AlterServerPerNode 函数:

    • AlterServerPerNode 函数用于修改指定服务的最小和最大实例数量。
    • 构建修改服务属性的请求 URL 和参数。
    • 发送 HTTP POST 请求以修改服务属性。
    • 检查响应以确保修改成功。
  6. 定义 assertJsonSuccess 函数:

    • assertJsonSuccess 函数用于检查 JSON 响应是否包含错误信息。
    • 如果 JSON 响应包含错误信息,函数返回 False,否则返回 True
  7. 在脚本的末尾,使用 if __name__ == "__main__": 来指示当脚本作为主程序运行时执行 main 函数。

参考资源

示例:编辑服务属性—ArcGIS Server | ArcGIS Enterprise 文档

ArcGIS Server服务中ArcSOC进程占用过多内存-百度经验 (baidu.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/69956.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

回复:c#的Winform如何让ComboBox不显示下拉框?https://bbs.csdn.net/topics/392565412

组合框.Parent this;组合框.Items.AddRange(new object[] { "111", "222", "333", "444" });组合框.DropDownHeight 1;组合框.SelectedIndex 0;//组合框.DropDownStyle ComboBoxStyle.Simple; ComboBox 组合框 new ComboBox();Li…

51单片机电子钟六位数码管显示整点提醒仿真设计( proteus仿真+程序+原理图+报告+讲解视频)

51单片机电子钟六位数码管显示整点提醒仿真设计( proteus仿真程序原理图报告讲解视频) 1.主要功能:2.仿真3. 程序代码4. 原理图参考元器件清单 5. 设计报告6. 设计资料内容清单 51单片机电子钟六位数码管显示整点提醒仿真设计( proteus仿真程序原理图报告…

[HDCTF 2023]YamiYami

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言涉及知识点解题详细过程session伪造反弹shell 前言 从暑假末尾一直搁置,当时卡在反弹shell搞得离flag就差一步。不过最近一两天学习完反弹shell的知…

8.(Python数模)(预测模型一)马尔科夫链预测

Python实现马尔科夫链预测 马尔科夫链原理 马尔科夫链是一种进行预测的方法,常用于系统未来时刻情况只和现在有关,而与过去无关。 用下面这个例子来讲述马尔科夫链。 如何预测下一时刻计算机发生故障的概率? 当前状态只存在0(故…

虚拟机扩容

系统环境centos8,分两步,第一步先在vmware扩容,第二部在虚拟机内部扩容 1.vmware分配磁盘空间 2.虚拟机内部扩容 查看当前磁盘信息,这个是扩容之前的,扩容完成才会显示新的 df -h查看系统分区信息 fdisk -l查看目录…

C语言基础知识理论版(很详细)

文章目录 前述一、数据1.1 数据类型1.2 数据第一种数据:常量第二种数据:变量第三种数据:表达式1、算术运算符及算术表达式2、赋值运算符及赋值表达式3、自增、自减运算符4、逗号运算符及其表达式(‘顺序求值’表达式)5…

Spring Boot日志基础使用 设置日志级别

然后 我们来说日志 日志在实际开发中还是非常重要的 即可记录项目状态和一些特殊情况发生 因为 我们这里不是将项目 所以 讲的也不会特别深 基本还是将Spring Boot的日志设置或控制这一类的东西 相对业务的领域我们就不涉及了 日志 log 初期最明显的作用在于 开发中 你可以用…

深入浅出了解BeanFactory 和 ApplicationContext

一.区别 BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。 1.依赖关系 BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean…

Mac 手动安装 sshpass

1. 下载安装包 https://sourceforge.net/projects/sshpass/ 解压并进入到安装包目录 tar -zxvf sshpass-xx.xx.tar.gz cd sshpass-xx.xx2. 检验环境,编译源码安装 ./configuremake&&make install3. 检测安装是否成功 ▶ sshpass Usage: sshpass [-f|-…

Golang专题精进

Golang专题精进 Golang单元测试Golang错误处理Golang正则表达式Golang反射Golang验证码Golang日期时间处理库CarbonGolang发送邮件库emailGolang log日志Golang log日志框架logrusGolang加密和解密应用Golang访问权限控制框架casbinGolang使用swagger生成api接口文档Golang jwt…

Vue + Element UI 实现权限管理系统 前端篇(十四):菜单功能实现菜

Vue Element UI 实现权限管理系统 前端篇(十四):菜单功能实现 菜单功能实现 菜单接口封装 菜单管理是一个对菜单树结构的增删改查操作。 提供一个菜单查询接口,查询整颗菜单树形结构。 http/modules/menu.js 添加 findMenu…

uniapp 解决跨域的问题

uniapp 解决跨域的问题 我真的是个 沙雕 找对了解决办法 写错了地方 "h5" : {"devServer" : {"disableHostCheck" : true,"https": false,"proxy" : {"/app" : {"target" : "https://192.16…

MRI多任务技术及应用

目录 一、定量心血管磁共振成像(CMR)的改进方法二、磁共振多任务三、磁共振多任务的成像框架四、磁共振多任务的图像模型和采样和重建策略五、利用MR多任务进行快速三维稳态CEST(ss-CEST)成像5.1 利用MR多任务进行快速三维稳态CEST(ss-CEST)成像介绍5.2 …

Java调用Web Service接口

方法1. 用IDEA生成相关代码调用方法。 在IDEA插件商店下载插件 然后新建一个Java项目 创建一个包来存放生成的代码,(点击一下)选中这个包,点击Tools 填入接口url,记住后面拼接“?wsdl”,选择生成方法,然后OK即可生…

超详解| Yolov8模型手把手调参 | 配置 | 模型训练 | 验证 | 推理

YOLOv8是一款前沿、最先进(SOTA)的模型,基于先前YOLO版本的成功,引入了新功能和改进,进一步提升性能和灵活性。 然而,要充分发挥Yolov8的潜力,合理的参数配置是至关重要的。本文将带您深入了解…

stable diffusion实践操作-VAE

系列文章总目录 stable diffusion实践操作 文章目录 系列文章总目录一、 前言1 定义功能全局介绍2 模型全局介绍2.1 后缀以及存放位置2.2 查看大模型是否有VAE 二、正文1 原理1.1 基础原理 2 使用2.1 增加饱和度2.2 增加细节 3 下载3.1 自动下载3.2 手动下载 三 、总结 一、 前…

掌握逻辑漏洞复现技术,保护您的数字环境

环境准备 这篇文章旨在用于网络安全学习,请勿进行任何非法行为,否则后果自负。 1、支付逻辑漏洞 攻击相关介绍 介绍: 支付逻辑漏洞是指攻击者利用支付系统的漏洞,突破系统的限制,完成非法的支付操作。攻击者可以采…

从0到1构建界面设计系统思维

用户界面(UI)是人与机器之间发生交互的载体,也是用户体验(UX)的一个组成部分。用户界面由两个主要部分组成:视觉设计(即传达产品的外观和感觉)和交互设计(即元素的功能和…

实现SSE的textevent-stream是什么?和applicationoctet-stream有什么区别?

WEB通讯技术。前端实现SSE长连接,nodejsexpress搭建简单服务器,进行接口调试,通过curl请求数据 点击上面的地址是可以了解轮询和长轮询以及websocket等通信模式,一些基础概念和速成技能,这篇来接着详细聊聊text/event…

Qt---对话框 事件处理 如何发布自己写的软件

目录 一、对话框 1.1 消息对话框(QMessageBox) 1> 消息对话框提供了一个模态的对话框,用来提示用户信息,或者询问用户问题并得到回答 2> 基于属性版本的API 3> 基于静态成员函数版本 4> 对话框案例 1、ui界面 …