亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

Nashorn沙箱技術

2023-05-26 01:49:28
188
0

從Java 8開始(nashorn在Java 15中去掉了),可以使用nashorn來執行Javascript代碼,使用方法如下:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.;

Nashorn提供了非常簡單的方式讓用戶可以在JS代碼中引用Java的方法

public class NashornTest {
	@Test
	public void test() throws ScriptException {
		String js = "var test = Java.type('test.NashornTest'); test.printName('abc')";
		ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
		engine.;
	}

	public static void printName(String name) {
		System.out.println("name is " + name);
	}
}

Nashorn雖然強大,但如果在生產環境中使用Nashorn來執行用戶自己寫的JS代碼還是得考慮以下問題:

1,如何防止用戶在JS中使用比較危險的Java方法,如System.exit()?

2,如何防止用戶的JS占用過多的內存和CPU資源?

3,如何提升JS執行的并發性能?

 

delight.nashornsandbox項目為開發者提供了Nashorn沙箱環境來執行JS代碼,解決以上問題

1,可以在初始化Nashorn沙箱時定義一個白名單,只允許JS引用白名單中的Java類

public class NashornTest {
	public static void printName(String name) {
		System.out.println("name is " + name);
	}

	@Test
	public void testSandbox() throws ScriptCPUAbuseException, ScriptException {
		String js = "var test = Java.type('test.NashornTest'); test.printName('abc')";
		NashornSandbox sandbox = NashornSandboxes.create("--language=es6");
		// 允許JS中引用NashornTest類
		sandbox.allow(NashornTest.class);
		sandbox.;
	}
}

2,設置線程每次執行JS使用的CPU和內存上限,需要指定ExecutorService作為JS的線程執行器

ExecutorService executor = Executors.newCachedThreadPool();
NashornSandbox sandbox = NashornSandboxes.create("--language=es6");
// 允許JS中引用NashornTest類
sandbox.allow(NashornTest.class);
// 設置CPU時間上限為3000毫秒,在JS中sleep并不占用這個時間
sandbox.setMaxCPUTime(3000);
// 設置內存上限為5MB
sandbox.setMaxMemory(5 * 1024 * 1024);
sandbox.allowNoBraces(false);
sandbox.allowLoadFunctions(true);
sandbox.allowPrintFunctions(true);
// 設置緩存JS代碼數量,JS預編譯后緩存起來
sandbox.setMaxPreparedStatements(50);
sandbox.setExecutor(executor);

如果設置了CPU和內存上限,Nashorn沙箱在執行JS的時候,就會額外啟動一個監控線程,這個監控線程就會循環去調用ThreadMXBean.getThreadAllocatedBytes(執行線程Id) 和ThreadMXBean.getThreadCpuTime(執行線程Id) 這兩個方法來判斷CPU和內存是否達到上限,如果其中一個達到上限,則會中斷JS的執行并拋出異常。

需要注意的是,ThreadMXBean.getThreadAllocatedBytes并不是返回指定線程所創建的對象目前占用的堆內存大小,而是返回指定線程已經分配的內存大小(已分配的內存可能已經被釋放)

3,并發調用的性能問題,

1)可以創建一個Nashorn沙箱池,省去頻繁創建和銷毀沙箱的開銷

2)設置緩存JS代碼數量,提高JS執行速度,sandbox.setMaxPreparedStatements(maxCacheSize);

public class NashornSandboxFactory implements PoolObjectFactory<NashornSandbox> {

	private ExecutorService executor;
	private long maxCpuTime;
	private long maxMemorySize;
	private int maxCacheSize;

	/**
	 * @param executor
	 * @param maxCpuTime    最大CPU時間,毫秒
	 * @param maxMemorySize 最大內存,byte
	 * @param maxCacheSize  最大腳本緩存個數
	 */
	public NashornSandboxFactory(ExecutorService executor, long maxCpuTime, long maxMemorySize, int maxCacheSize) {
		this.executor = executor;
		this.maxCpuTime = maxCpuTime;
		this.maxMemorySize = maxMemorySize;
		this.maxCacheSize = maxCacheSize;
	}

	@Override
	public NashornSandbox create() {
		NashornSandbox sandbox = NashornSandboxes.create("--language=es6");
		// 沙箱初始化
		return sandbox;
	}

	@Override
	public boolean readyToTake(NashornSandbox obj) {
		return true;
	}

	@Override
	public boolean readyToRestore(NashornSandbox obj) {
		return true;
	}

	@Override
	public void destroy(NashornSandbox obj) {
		// do nothing
	}
PoolService<NashornSandbox> pool = new ConcurrentPool<>(new ConcurrentLinkedQueueCollection<>(), factory, coreSize, maxSize, false);
NashornSandbox sandbox = pool.tryTake(timeout, TimeUnit.MILLISECONDS);
sandbox.;

雖然Java 15已經去掉了nashorn,但可以在pom.xml中單獨引入

        <dependency>
            <groupId>org.openjdk.nashorn</groupId>
            <artifactId>nashorn-core</artifactId>
            <version>15.3</version>
        </dependency>
0條評論
0 / 1000
白龍馬
14文章數
0粉絲數
白龍馬
14 文章 | 0 粉絲
原創

Nashorn沙箱技術

2023-05-26 01:49:28
188
0

從Java 8開始(nashorn在Java 15中去掉了),可以使用nashorn來執行Javascript代碼,使用方法如下:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.;

Nashorn提供了非常簡單的方式讓用戶可以在JS代碼中引用Java的方法

public class NashornTest {
	@Test
	public void test() throws ScriptException {
		String js = "var test = Java.type('test.NashornTest'); test.printName('abc')";
		ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
		engine.;
	}

	public static void printName(String name) {
		System.out.println("name is " + name);
	}
}

Nashorn雖然強大,但如果在生產環境中使用Nashorn來執行用戶自己寫的JS代碼還是得考慮以下問題:

1,如何防止用戶在JS中使用比較危險的Java方法,如System.exit()?

2,如何防止用戶的JS占用過多的內存和CPU資源?

3,如何提升JS執行的并發性能?

 

delight.nashornsandbox項目為開發者提供了Nashorn沙箱環境來執行JS代碼,解決以上問題

1,可以在初始化Nashorn沙箱時定義一個白名單,只允許JS引用白名單中的Java類

public class NashornTest {
	public static void printName(String name) {
		System.out.println("name is " + name);
	}

	@Test
	public void testSandbox() throws ScriptCPUAbuseException, ScriptException {
		String js = "var test = Java.type('test.NashornTest'); test.printName('abc')";
		NashornSandbox sandbox = NashornSandboxes.create("--language=es6");
		// 允許JS中引用NashornTest類
		sandbox.allow(NashornTest.class);
		sandbox.;
	}
}

2,設置線程每次執行JS使用的CPU和內存上限,需要指定ExecutorService作為JS的線程執行器

ExecutorService executor = Executors.newCachedThreadPool();
NashornSandbox sandbox = NashornSandboxes.create("--language=es6");
// 允許JS中引用NashornTest類
sandbox.allow(NashornTest.class);
// 設置CPU時間上限為3000毫秒,在JS中sleep并不占用這個時間
sandbox.setMaxCPUTime(3000);
// 設置內存上限為5MB
sandbox.setMaxMemory(5 * 1024 * 1024);
sandbox.allowNoBraces(false);
sandbox.allowLoadFunctions(true);
sandbox.allowPrintFunctions(true);
// 設置緩存JS代碼數量,JS預編譯后緩存起來
sandbox.setMaxPreparedStatements(50);
sandbox.setExecutor(executor);

如果設置了CPU和內存上限,Nashorn沙箱在執行JS的時候,就會額外啟動一個監控線程,這個監控線程就會循環去調用ThreadMXBean.getThreadAllocatedBytes(執行線程Id) 和ThreadMXBean.getThreadCpuTime(執行線程Id) 這兩個方法來判斷CPU和內存是否達到上限,如果其中一個達到上限,則會中斷JS的執行并拋出異常。

需要注意的是,ThreadMXBean.getThreadAllocatedBytes并不是返回指定線程所創建的對象目前占用的堆內存大小,而是返回指定線程已經分配的內存大小(已分配的內存可能已經被釋放)

3,并發調用的性能問題,

1)可以創建一個Nashorn沙箱池,省去頻繁創建和銷毀沙箱的開銷

2)設置緩存JS代碼數量,提高JS執行速度,sandbox.setMaxPreparedStatements(maxCacheSize);

public class NashornSandboxFactory implements PoolObjectFactory<NashornSandbox> {

	private ExecutorService executor;
	private long maxCpuTime;
	private long maxMemorySize;
	private int maxCacheSize;

	/**
	 * @param executor
	 * @param maxCpuTime    最大CPU時間,毫秒
	 * @param maxMemorySize 最大內存,byte
	 * @param maxCacheSize  最大腳本緩存個數
	 */
	public NashornSandboxFactory(ExecutorService executor, long maxCpuTime, long maxMemorySize, int maxCacheSize) {
		this.executor = executor;
		this.maxCpuTime = maxCpuTime;
		this.maxMemorySize = maxMemorySize;
		this.maxCacheSize = maxCacheSize;
	}

	@Override
	public NashornSandbox create() {
		NashornSandbox sandbox = NashornSandboxes.create("--language=es6");
		// 沙箱初始化
		return sandbox;
	}

	@Override
	public boolean readyToTake(NashornSandbox obj) {
		return true;
	}

	@Override
	public boolean readyToRestore(NashornSandbox obj) {
		return true;
	}

	@Override
	public void destroy(NashornSandbox obj) {
		// do nothing
	}
PoolService<NashornSandbox> pool = new ConcurrentPool<>(new ConcurrentLinkedQueueCollection<>(), factory, coreSize, maxSize, false);
NashornSandbox sandbox = pool.tryTake(timeout, TimeUnit.MILLISECONDS);
sandbox.;

雖然Java 15已經去掉了nashorn,但可以在pom.xml中單獨引入

        <dependency>
            <groupId>org.openjdk.nashorn</groupId>
            <artifactId>nashorn-core</artifactId>
            <version>15.3</version>
        </dependency>
文章來自個人專欄
文章 | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0