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

这篇具有很好参考价值的文章主要介绍了py脚本解决ArcGIS Server服务内存过大的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

1. 现象

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

2. 解决方法

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

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

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

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

重启服务即可

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

3. 在浏览器中打开

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

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)文章来源地址https://www.toymoban.com/news/detail-696845.html

到了这里,关于py脚本解决ArcGIS Server服务内存过大的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 小程序:uniapp解决主包体积过大的问题

    已经分包但还是体积过大 运行时勾选“运行时是否压缩代码”进行压缩 在 manifest.json 配置(开启分包优化) 在 app.json 配置(设置组件按需注入)

    2024年02月07日
    浏览(37)
  • 关于VMware虚拟机创建时磁盘分配过大的解决方法

     写这个文章是因为在虚拟机创建之时给的硬盘空间太大,想压缩一下,到各大论坛搜索相关帖子,发现能解决问题的太少了,所幸最后成功压缩。 接下来分享一下我压缩虚拟机硬盘空间的经验 目录 1.首先打开虚拟机右键“此电脑”→“管理”→“磁盘管理”  2.找到我们要

    2024年02月05日
    浏览(42)
  • 解决gitee仓库中 .git 文件夹过大的问题

    最近,许多项目都迁移到gitee。使用的也越来越频繁,但是今天突然收到一个仓库爆满的提示。让我一脸懵逼。本文将详细为你解答,这种情况如何处理。 我收到的报错如下: 看了下,大概意思是一个仓库体积最大不能超过1GB,但是现在我已经超过3GB了。。。 我第一个想法

    2024年02月03日
    浏览(34)
  • 微信小程序:uniapp解决上传小程序体积过大的问题

    在昨天的工作中遇到了一个微信小程序上传代码过大的情况,在这里总结一下具体的解决步骤,首先介绍一下,技术栈是使用uniapp框架+HBuilderX的开发环境。 错误提示 真机调试,提示包提交过大,不能正常生成二维码,后续上传代码更是不可能了,减少包中的体积顺着这条思

    2024年02月03日
    浏览(35)
  • 实际生产环境Apache RocketMQ消息体过大的解决方案

    官方定义消息体默认大小为 4MB,普通顺序消息类型。事务、定时、延时类消息默认大小为64KB。如果超过限制则会抛出异常! 但实际工作中,需要使用到MQ进行异步解耦,传输的业务消息偶尔会遇到超过4MB,尤其在业务复杂的系统中,那么我们应该如何处理呢? 在我工作实际

    2024年01月16日
    浏览(37)
  • VMware 虚拟机占用磁盘空间过大的一种解决方案

    在使用VMware虚拟机的过程中,VM会自动扩大虚拟磁盘的占用空间。发现无论是VM自带的碎片整理还是压缩,这两个操作都无法明显减少虚拟机占用空间。 现在找到一种方法可以做到这点( 可能只适用于VM workstation pro,并未测试过普通版本 ),下面是方法的整理 1.正常关闭虚拟

    2024年02月13日
    浏览(66)
  • git仓库清理瘦身解决 .git文件夹过大的问题

    git仓库清理找了很多资料和方案都没有很完美执行成功的;现在找到一个完美方案,分享给大家;希望能帮助大家 1、gitlab代码开发了仓库开发了五年了,代码只有10M;clone的时候要700多兆很浪费时间 2、创建分支和切换分支耗时,导致电脑崩溃 3、公司内部接入codereview服务;

    2024年02月02日
    浏览(49)
  • 微信小程序中使用字体图标,解决字体图标包过大的问题

    在微信小程序开发中,我们经常使用字体图标来美化界面和展示各种功能。然而,当我们的小程序主包大小超过2M时,可能会遇到一个问题:字体图标的文件很大,导致整个包的大小超出了限制。为了解决这个问题,我们可以使用wx.loadFontFace方法来远程加载字体图标。 步骤一

    2024年02月12日
    浏览(59)
  • 解决Hadoop审计日志hdfs-audit.log过大的问题

    新搭建的Hadoop环境没怎么用,就一个环境天天空跑,结果今天运维告诉我说有一台服务器磁盘超过80%了,真是太奇怪了,平台上就跑了几个spark测试程序,哪来的数据呢? 既然是磁盘写满了,那首先就要找到具体是什么数据写满的磁盘。 用df查看,是根目录,还不是数据盘;

    2024年02月14日
    浏览(61)
  • Linux 清理磁盘空间&使用du指令排查服务器磁盘占用过大的文件

    命令:df -h 参数说明: -a:列出所有的文件系统,包括系统特有的/proc等文件系统 -k:以KB的容器显示各文件系统 -m:以MB的容量显示各文件系统 -h:以人们较易阅读的GB,MB,KB等格式自行显示 -H:以 M=1000K代替M=1024K的进位方式 -T:连同该分区的文件系统名称(例如ext3)也列出

    2024年02月06日
    浏览(42)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包