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

news2024/11/25 5:18:56

在一台服务器上,使用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 info
    print
    print("This tool is a sample script that resets the minimum and maximum instances allowed for a service.")
    print
    serverName ="127.0.01" #raw_input("Enter Server name: ")
    serverPort = 6080
    username ="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 numerical
    try:
        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 maximum
    if minInstancesNum > maxInstancesNum:
        print("Maximum number of instances must be greater or equal to minimum number.")
        return
    # Get a token
    token = getToken(username, password, serverName, serverPort)
    if token == "":
        print("Could not generate a token with the username and password provided.")
        return
    service_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/generateToken
    tokenURL = "/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 parameters
    httpConn = http.client.HTTPConnection(serverName, serverPort)
    httpConn.request("POST", tokenURL, params, headers)
    # Read response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print("Error while fetching tokens from admin URL. Please check the URL and try again.")
        return
    else:
        data = response.read()
        httpConn.close()
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):            
            return
        # Extract the token from it
        token = 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 parameter
    params = urllib.parse.urlencode({'token': token, 'f': 'json'})
    serviceURL=service_base_url+"?"+params
    response=requests.get(serviceURL)
    # httpConn.request("Post", serviceURL, params, headers)
    # Read response
    if (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_names

def 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 parameter
    params = 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 response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print("Could not read service information.")
        return
    else:
        data = response.read()
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):          
            print("Error when reading service information. " + str(data))
        else:
            print("Service information read successfully. Now changing properties...")
        # Deserialize response into Python object
        dataObj = json.loads(data)
        if dataObj["minInstancesPerNode"]!=minInstancesNum or dataObj["maxInstancesPerNode"] != maxInstancesNum:
            # Edit desired properties of the service
            dataObj["minInstancesPerNode"] = minInstancesNum
            dataObj["maxInstancesPerNode"] = maxInstancesNum
            # Serialize back into JSON
            updatedSvcJson = 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 response
            editResponse = httpConn.getresponse()
            if (editResponse.status != 200):
                httpConn.close()
                print("Error while executing edit.")
                return
            else:
                editData = editResponse.read()
                # Check that data returned is not an error object
                if 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 False
    else:
        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.coloradmin.cn/o/980273.html

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

相关文章

并行和并发的区别

从操作系统的角度来看,线程是CPU分配的最小单位。 并行就是同一时刻,两个线程都在执行。这就要求有两个CPU去分别执行两个线程。并发就是同一时刻,只有一个执行,但是一个时间段内,两个线程都执行了。并发的实现依赖于…

立晶半导体Cubic Lattice Inc 专攻音频ADC,音频DAC,音频CODEC,音频CLASS D等CL7016

概述: CL7016是一款高保真USB Type-C兼容音频编解码芯片。可以录制和回放有24比特音乐和声音。内置回放通路信号动态压缩, 最大42db录音通路增益,PDM数字麦克风,和立体声无需电容耳机驱动放大器。 5V单电源供电。兼容USB 2.0全速工…

三分法,伟大无比的二分法扩展,本节带部分数论问题。

一,引导简介 简单的来看三分法实际就是二分法的另一种扩展,可以完全的看成二分法,我们介绍几个特殊的点,才能使用这个解法来进行相关的算法求解:求解单调性改变的点,在本个区间中只有一个导数为 0 的点&…

基于qt软件的网上聊天室软件

1.服务器: 1).功能: 用于创建一个客户端,通过文本编辑器来获得端口号,根据获得的端口号创建服务器,等待客户端连接 创建成功会提示服务器创建成功 在收到客户端发送的信息时,把这条信息发送给其他所有客户端,实现群…

力扣(LeetCode)算法_C++——有效的数独

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) …

vue3集成jsoneditor

一、背景 之前在做录制回放平台的时候,需要前端展示子调用信息,子调用是一个请求列表数组结构,jsoneditor对数组的默认展示结构是[0].[1].[2]..的方式,为了达到如下的效果,必须用到 onNodeName的钩子函数,…

使用Minifilter过滤驱动保护文件

代码如下: 可以保护拓展名.com文件不被删除、重命名、读写、可执行。#include <ntifs.h> #include <ntstrsafe.h> #include <fltKernel.h> static UNICODE_STRING ProtectedExtention RTL_CONSTANT_STRING(L"com"); //卸载回调 PFLT_FILTER gFile…

如何写一个可以找到工作的简历不至于太烂

简历是自己的一个很重要的标签&#xff0c;是获得面试的敲门砖&#xff0c;简历是要时常更新的&#xff0c;否则会错过一些机会。简历也是给自己的正反馈。 方法 ● 模仿&#xff0c;例如Boss&#xff0c;拉钩下面都给你一个案例模板供你参考&#xff0c;但是我觉得其实参考性…

基础算法--二分查找

二分查找 算法原理 1. 简介 故事分享&#x1f3ec;&#xff1a; 有一天小明到图书馆借了 N 本书&#xff0c;出图书馆的时候&#xff0c;警报响了&#xff0c;于是保安把小明拦下&#xff0c;要检查一下哪本书没有登记出借。小明正准备把每一本书在报警器下过一下&#xff0…

C语言基本知识

基础 第一个函数 argc代表参数个数argument count。argv代表参数value&#xff0c;第一个为放的是文件名&#xff0c;后面是传入的参数。 编译过程 预处&#xff1a;gcc -E hello.c -o hello.i编译&#xff1a;gcc -S hello.c(.i) -o hello.s汇编&#xff1a;gcc -c hello.c…

2023年09月数据库流行度最新排名

点击查看最新数据库流行度最新排名&#xff08;每月更新&#xff09; 2023年09月数据库流行度最新排名 TOP DB顶级数据库索引是通过分析在谷歌上搜索数据库名称的频率来创建的 一个数据库被搜索的次数越多&#xff0c;这个数据库就被认为越受欢迎。这是一个领先指标。原始数…

C语言“牵手”1688商品详情数据方法,1688商品详情API接口,1688API申请指南

1688是中国最大的自营式电商企业&#xff0c;在线销售计算机、手机及其它数码产品、家电、汽车配件、服装与鞋类、奢侈品、家居与家庭用品、化妆品与其它个人护理用品、食品与营养品、书籍与其它媒体产品、母婴用品与玩具、体育与健身器材以及虚拟商品等。 1688平台的商品详情…

route命令小结

Destination: 如果不满足该列的任何一个ip,则走默认的default Gataway: *是 不指定gateway.有的系统是0.0.0.0,与*意义相同 Genmask: 0.0.0.0是不指定掩码, 255.255.0.0掩码了16位,172.17 开头的ip,会走这个网关 255.255.255.0掩码了16位,192.168.0 开头的ip都会走这个网关 当是…

基于Alexnet深度学习网络的人员口罩识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 file_path1 test\mask\;% 图像文件夹路径 %获取测试图像文件夹下所有jpg格式的图像文件…

网工内推 | 国企专场,网络运维工程师,华为/思科认证优先

01 中百集团 招聘岗位&#xff1a;运维工程师 职责描述&#xff1a; 1、对集团内使用云计算架构&#xff08;Kubernetes&#xff09;的系统进行规划、运维及管理相关工作。 2、对集团数据中心系统的大数据基础架构&#xff08;Cloudera Distribution Hadoop&#xff09;的规划…

vue3项目修改浏览器的项目icon小图标

修改vue3项目的浏览器的图标 vue2修改图标

微信的标签怎样管理?怎样标签群发更高效?(建议收藏)

01 管理标签的意义 随着时间的递增&#xff0c;微信好友越来越多&#xff0c;很容易就超过了上千人&#xff0c;如果这时候&#xff0c;还没有具备管理标签的意识&#xff0c;那就必须得提上日程了。 管理标签有如下几点意义&#xff1a; 1、方便找到对方 2、分组备注&am…

HarmonyOS/OpenHarmony(Stage模型)应用开发单一手势(三)

五、旋转手势&#xff08;RotationGesture&#xff09; RotationGesture(value?:{fingers?:number; angle?:number}) 旋转手势用于触发旋转手势事件&#xff0c;触发旋转手势的最少手指数量为2指&#xff0c;最大为5指&#xff0c;最小改变度数为1度&#xff0c;拥有两个可…

分享一下在微信上有哪些微信活动可以做

微信营销活动是吸引更多用户和提高品牌知名度的有效策略。下面是一些微信营销活动的做法&#xff1a; 抽奖活动&#xff1a;通过设置奖品和参与条件&#xff0c;吸引用户参与抽奖活动。例如&#xff0c;可以设置关注公众号、转发活动页面等条件&#xff0c;吸引更多用户参与抽奖…

Redis 分布式锁

面试题&#xff1a; Redis除了拿来做缓存&#xff0c;你还见过基于Redis的什么用法&#xff1f; 1.数据共享&#xff0c;分布式Session 2.分布式锁 3.全局ID 4.计算器、点赞 5.位统计 6.购物车 7.轻量级消息队列&#xff1a;list、stream 8.抽奖 9.点赞、签到、打卡 10.差集交集…