栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

J2V8--java调用JS文件执行js函数的高效类库,高并发下表现依然高效

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

J2V8--java调用JS文件执行js函数的高效类库,高并发下表现依然高效

前言

现有需求需要前端传入账号密码,调用后台接口返回加密授权数据,而通过账号密码获取授权信息的算法是从其他站点爬到的js中实现的,无法通过Java后端重写一套算法.因此需要把js放在Java中执行

优化

前端给的实现方式,采用scriptEngine实现

JS文件

var window={};var navigator={};$=window.$||{},pt=window.pt||{},RSA=pt.RSA=function(){function t(t,e){return new r(t,e)}
function e(t,e){if(e=0&&e>0;){var o=t.charCodeAt(n--);i[--e]=o}
i[--e]=0;for(var p=new Y,s=new Array;e>2;){for(s[0]=0;0==s[0];)p.nextBytes(s);i[--e]=s[0]}
return i[--e]=2,i[--e]=0,new r(i)}
function i(){this.n=null,this.e=0,this.d=null,this.p=null,this.q=null,this.dmp1=null,this.dmq1=null,this.coeff=null}
function n(e,i){null!=e&&null!=i&&e.length>0&&i.length>0?(this.n=t(e,16),this.e=parseInt(i,16)):uv_alert("Invalid RSA public key")}
function o(t){return t.modPowInt(this.e,this.n)}
function p(t){var i=e(t,this.n.bitLength()+7>>3);if(null==i)return null;var n=this.doPublic(i);if(null==n)return null;var o=n.toString(16);return 0==(1&o.length)?o:"0"+o}
function r(t,e,i){null!=t&&("number"==typeof t?this.fromNumber(t,e,i):null==e&&"string"!=typeof t?this.fromString(t,256):this.fromString(t,e))}
function s(){return new r(null)}
function l(t,e,i,n,o,p){for(;--p>=0;){var r=e*this[t++]+i[n]+o;o=Math.floor(r/67108864),i[n++]=67108863&r}
return o}
function a(t,e,i,n,o,p){for(var r=32767&e,s=e>>15;--p>=0;){var l=32767&this[t],a=this[t++]>>15,c=s*l+a*r;l=r*l+((32767&c)<<15)+i[n]+(1073741823&o),o=(l>>>30)+(c>>>15)+s*a+(o>>>30),i[n++]=1073741823&l}
return o}
function c(t,e,i,n,o,p){for(var r=16383&e,s=e>>14;--p>=0;){var l=16383&this[t],a=this[t++]>>14,c=s*l+a*r;l=r*l+((16383&c)<<14)+i[n]+o,o=(l>>28)+(c>>14)+s*a,i[n++]=268435455&l}
return o}
function u(t){return ut.charAt(t)}
function g(t,e){var i=gt[t.charCodeAt(e)];return null==i?-1:i}
function d(t){for(var e=this.t-1;e>=0;--e)t[e]=this[e];t.t=this.t,t.s=this.s}
function h(t){this.t=1,this.s=0>t?-1:0,t>0?this[0]=t:-1>t?this[0]=t+DV:this.t=0}
function f(t){var e=s();return e.fromInt(t),e}
function m(t,e){var i;if(16==e)i=4;else if(8==e)i=3;else if(256==e)i=8;else if(2==e)i=1;else if(32==e)i=5;else{if(4!=e)return void this.fromRadix(t,e);i=2}
this.t=0,this.s=0;for(var n=t.length,o=!1,p=0;--n>=0;){var s=8==i?255&t[n]:g(t,n);0>s?"-"==t.charAt(n)&&(o=!0):(o=!1,0==p?this[this.t++]=s:p+i>this.DB?(this[this.t-1]|=(s&(1<>this.DB-p):this[this.t-1]|=s<=this.DB&&(p-=this.DB))}
8==i&&0!=(128&t[0])&&(this.s=-1,p>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==t;)--this.t}
function $(t){if(this.s<0)return"-"+this.negate().toString(t);var e;if(16==t)e=4;else if(8==t)e=3;else if(2==t)e=1;else if(32==t)e=5;else{if(4!=t)return this.toRadix(t);e=2}
var i,n=(1<0)for(s>s)>0&&(o=!0,p=u(i));r>=0;)e>s?(i=(this[r]&(1<>(s+=this.DB-e)):(i=this[r]>>(s-=e)&n,0>=s&&(s+=this.DB,--r)),i>0&&(o=!0),o&&(p+=u(i));return o?p:"0"}
function v(){var t=s();return r.ZERO.subTo(this,t),t}
function w(){return this.s<0?this.negate():this}
function y(t){var e=this.s-t.s;if(0!=e)return e;var i=this.t;if(e=i-t.t,0!=e)return e;for(;--i>=0;)if(0!=(e=this[i]-t[i]))return e;return 0}
function k(t){var e,i=1;return 0!=(e=t>>>16)&&(t=e,i+=16),0!=(e=t>>8)&&(t=e,i+=8),0!=(e=t>>4)&&(t=e,i+=4),0!=(e=t>>2)&&(t=e,i+=2),0!=(e=t>>1)&&(t=e,i+=1),i}
function b(){return this.t<=0?0:this.DB*(this.t-1)+k(this[this.t-1]^this.s&this.DM)}
function q(t,e){var i;for(i=this.t-1;i>=0;--i)e[i+t]=this[i];for(i=t-1;i>=0;--i)e[i]=0;e.t=this.t+t,e.s=this.s}
function S(t,e){for(var i=t;i=0;--i)e[i+r+1]=this[i]>>o|s,s=(this[i]&p)<=0;--i)e[i]=0;e[r]=s,e.t=this.t+r+1,e.s=this.s,e.clamp()}
function C(t,e){e.s=this.s;var i=Math.floor(t/this.DB);if(i>=this.t)return void(e.t=0);var n=t%this.DB,o=this.DB-n,p=(1<>n;for(var r=i+1;r>n;n>0&&(e[this.t-i-1]|=(this.s&p)<i;)n+=this[i]-t[i],e[i++]=n&this.DM,n>>=this.DB;if(t.t>=this.DB;n+=this.s}
else{for(n+=this.s;i>=this.DB;n-=t.s}
e.s=0>n?-1:0,-1>n?e[i++]=this.DV+n:n>0&&(e[i++]=n),e.t=i,e.clamp()}
function L(t,e){var i=this.abs(),n=t.abs(),o=i.t;for(e.t=o+n.t;--o>=0;)e[o]=0;for(o=0;o=0;)t[i]=0;for(i=0;i=e.DV&&(t[i+e.t]-=e.DV,t[i+e.t+1]=1)}
t.t>0&&(t[t.t-1]+=e.am(i,e[i],t,2*i,0,1)),t.s=0,t.clamp()}
function E(t,e,i){var n=t.abs();if(!(n.t<=0)){var o=this.abs();if(o.t0?(n.lShiftTo(c,p),o.lShiftTo(c,i)):(n.copyTo(p),o.copyTo(i));var u=p.t,g=p[u-1];if(0!=g){var d=g*(1<1?p[u-2]>>this.F2:0),h=this.FV/d,f=(1<=0&&(i[i.t++]=1,i.subTo(v,i)),r.ONE.dlShiftTo(u,v),v.subTo(p,p);p.t=0;){var w=i[--_]==g?this.DM:Math.floor(i[_]*h+(i[_-1]+m)*f);if((i[_]+=p.am(0,w,i,$,0,u))0&&i.rShiftTo(c,i),0>l&&r.ZERO.subTo(i,i)}}}
function A(t){var e=s();return this.abs().divRemTo(t,null,e),this.s<0&&e.compareTo(r.ZERO)>0&&t.subTo(e,e),e}
function P(t){this.m=t}
function I(t){return t.s<0||t.compareTo(this.m)>=0?t.mod(this.m):t}
function H(t){return t}
function M(t){t.divRemTo(this.m,null,t)}
function Q(t,e,i){t.multiplyTo(e,i),this.reduce(i)}
function D(t,e){t.squareTo(e),this.reduce(e)}
function V(){if(this.t<1)return 0;var t=this[0];if(0==(1&t))return 0;var e=3&t;return e=e*(2-(15&t)*e)&15,e=e*(2-(255&t)*e)&255,e=e*(2-((65535&t)*e&65535))&65535,e=e*(2-t*e%this.DV)%this.DV,e>0?this.DV-e:-e}
function j(t){this.m=t,this.mp=t.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(e,e),e}
function O(t){var e=s();return t.copyTo(e),this.reduce(e),e}
function B(t){for(;t.t<=this.mt2;)t[t.t++]=0;for(var e=0;e>15)*this.mpl&this.um)<<15)&t.DM;for(i=e+this.m.t,t[i]+=this.m.am(0,n,t,e,0,this.m.t);t[i]>=t.DV;)t[i]-=t.DV,t[++i]++}
t.clamp(),t.drShiftTo(this.m.t,t),t.compareTo(this.m)>=0&&t.subTo(this.m,t)}
function R(t,e){t.squareTo(e),this.reduce(e)}
function F(t,e,i){t.multiplyTo(e,i),this.reduce(i)}
function z(){return 0==(this.t>0?1&this[0]:this.s)}
function G(t,e){if(t>4294967295||1>t)return r.ONE;var i=s(),n=s(),o=e.convert(this),p=k(t)-1;for(o.copyTo(i);--p>=0;)if(e.sqrTo(i,n),(t&1<0)e.mulTo(n,o,i);else{var l=i;i=n,n=l}
return e.revert(i)}
function W(t,e){var i;return i=256>t||e.isEven()?new P(e):new j(e),this.exp(t,i)}
function X(t){ht[ft++]^=255&t,ht[ft++]^=t>>8&255,ht[ft++]^=t>>16&255,ht[ft++]^=t>>24&255,ft>=$t&&(ft-=$t)}
function Z(){X((new Date).getTime())}
function K(){if(null==dt){for(Z(),dt=nt(),dt.init(ht),ft=0;fte;++e)this.S[e]=e;for(i=0,e=0;256>e;++e)i=i+this.S[e]+t[e%t.length]&255,n=this.S[e],this.S[e]=this.S[i],this.S[i]=n;this.i=0,this.j=0}
function it(){var t;return this.i=this.i+1&255,this.j=this.j+this.S[this.i]&255,t=this.S[this.i],this.S[this.i]=this.S[this.j],this.S[this.j]=t,this.S[t+this.S[this.i]&255]}
function nt(){return new tt}
function ot(t,e,n){e="e9a815ab9d6e86abbf33a4ac64e9196d5be44a09bd0ed6ae052914e1a865ac8331fed863de8ea697e9a7f63329e5e23cda09c72570f46775b7e39ea9670086f847d3c9c51963b131409b1e04265d9747419c635404ca651bbcbc87f99b8008f7f5824653e3658be4ba73e4480156b390bb73bc1f8b33578e7a4e12440e9396f2552c1aff1c92e797ebacdc37c109ab7bce2367a19c56a033ee04534723cc2558cb27368f5b9d32c04d12dbd86bbd68b1d99b7c349a8453ea75d1b2e94491ab30acf6c46a36a75b721b312bedf4e7aad21e54e9bcbcf8144c79b6e3c05eb4a1547750d224c0085d80e6da3907c3d945051c13c7c1dcefd6520ee8379c4f5231ed",n="10001";var o=new i;return o.setPublic(e,n),o.encrypt(t)}
i.prototype.doPublic=o,i.prototype.setPublic=n,i.prototype.encrypt=p;var pt,rt=0xdeadbeefcafe,st=15715070==(16777215&rt);st&&"Microsoft Internet Explorer"==navigator.appName?(r.prototype.am=a,pt=30):st&&"Netscape"!=navigator.appName?(r.prototype.am=l,pt=26):(r.prototype.am=c,pt=28),r.prototype.DB=pt,r.prototype.DM=(1<=ct;++ct)gt[at++]=ct;for(at="a".charCodeAt(0),ct=10;36>ct;++ct)gt[at++]=ct;for(at="A".charCodeAt(0),ct=10;36>ct;++ct)gt[at++]=ct;P.prototype.convert=I,P.prototype.revert=H,P.prototype.reduce=M,P.prototype.mulTo=Q,P.prototype.sqrTo=D,j.prototype.convert=U,j.prototype.revert=O,j.prototype.reduce=B,j.prototype.mulTo=F,j.prototype.sqrTo=R,r.prototype.copyTo=d,r.prototype.fromInt=h,r.prototype.fromString=m,r.prototype.clamp=_,r.prototype.dlShiftTo=q,r.prototype.drShiftTo=S,r.prototype.lShiftTo=T,r.prototype.rShiftTo=C,r.prototype.subTo=x,r.prototype.multiplyTo=L,r.prototype.squareTo=N,r.prototype.divRemTo=E,r.prototype.invDigit=V,r.prototype.isEven=z,r.prototype.exp=G,r.prototype.toString=$,r.prototype.negate=v,r.prototype.abs=w,r.prototype.compareTo=y,r.prototype.bitLength=b,r.prototype.mod=A,r.prototype.modPowInt=W,r.ZERO=f(0),r.ONE=f(1);var dt,ht,ft;if(null==ht){ht=new Array,ft=0;var mt;if("Netscape"==navigator.appName&&navigator.appVersion<"5"&&window.crypto&&window.crypto.random){var _t=window.crypto.random(32);for(mt=0;mt<_t.length;++mt)ht[ft++]=255&_t.charCodeAt(mt)}
for(;$t>ft;)mt=Math.floor(65536*Math.random()),ht[ft++]=mt>>>8,ht[ft++]=255&mt;ft=0,Z()}
Y.prototype.nextBytes=J,tt.prototype.init=et,tt.prototype.next=it;var $t=256;return{rsa_encrypt:ot}}
(),function(t){function e(){return Math.round(4294967295*Math.random())}
function i(t,e,i){(!i||i>4)&&(i=4);for(var n=0,o=e;e+i>o;o++)n<<=8,n|=t[o];return(4294967295&n)>>>0}
function n(t,e,i){t[e+3]=i>>0&255,t[e+2]=i>>8&255,t[e+1]=i>>16&255,t[e+0]=i>>24&255}
function o(t){if(!t)return"";for(var e="",i=0;ie;e++)i=t.charCodeAt(e),i>0&&127>=i?n.push(t.charAt(e)):i>=128&&2047>=i?n.push(String.fromCharCode(192|i>>6&31),String.fromCharCode(128|63&i)):i>=2048&&65535>=i&&n.push(String.fromCharCode(224|i>>12&15),String.fromCharCode(128|i>>6&63),String.fromCharCode(128|63&i));return n.join("")}
function l(t){_=new Array(8),$=new Array(8),v=w=0,b=!0,m=0;var i=t.length,n=0;m=(i+10)%8,0!=m&&(m=8-m),y=new Array(i+m+10),_[0]=255&(248&e()|m);for(var o=1;m>=o;o++)_[o]=255&e();m++;for(var o=0;8>o;o++)$[o]=0;for(n=1;2>=n;)8>m&&(_[m++]=255&e(),n++),8==m&&c();for(var o=0;i>0;)8>m&&(_[m++]=t[o++],i--),8==m&&c();for(n=1;7>=n;)8>m&&(_[m++]=0,n++),8==m&&c();return y}
function a(t){var e=0,i=new Array(8),n=t.length;if(k=t,n%8!=0||16>n)return null;if($=g(t),m=7&$[0],e=n-m-10,0>e)return null;for(var o=0;o=p;)if(8>m&&(m++,p++),8==m&&(i=t,!d()))return null;for(var o=0;0!=e;)if(8>m&&(y[o]=255&(i[w+m]^$[m]),o++,e--,m++),8==m&&(i=t,w=v-8,!d()))return null;for(p=1;8>p;p++){if(8>m){if(0!=(i[w+m]^$[m]))return null;m++}
if(8==m&&(i=t,w=v,!d()))return null}
return y}
function c(){for(var t=0;8>t;t++)_[t]^=b?$[t]:y[w+t];for(var e=u(_),t=0;8>t;t++)y[v+t]=e[t]^$[t],$[t]=_[t];w=v,v+=8,m=0,b=!1}
function u(t){for(var e=16,o=i(t,0,4),p=i(t,4,4),r=i(f,0,4),s=i(f,4,4),l=i(f,8,4),a=i(f,12,4),c=0,u=2654435769;e-->0;)c+=u,c=(4294967295&c)>>>0,o+=(p<<4)+r^p+c^(p>>>5)+s,o=(4294967295&o)>>>0,p+=(o<<4)+l^o+c^(o>>>5)+a,p=(4294967295&p)>>>0;var g=new Array(8);return n(g,0,o),n(g,4,p),g}
function g(t){for(var e=16,o=i(t,0,4),p=i(t,4,4),r=i(f,0,4),s=i(f,4,4),l=i(f,8,4),a=i(f,12,4),c=3816266640,u=2654435769;e-->0;)p-=(o<<4)+l^o+c^(o>>>5)+a,p=(4294967295&p)>>>0,o-=(p<<4)+r^p+c^(p>>>5)+s,o=(4294967295&o)>>>0,c-=u,c=(4294967295&c)>>>0;var g=new Array(8);return n(g,0,o),n(g,4,p),g}
function d(){for(var t=(k.length,0);8>t;t++)$[t]^=k[v+t];return $=g($),v+=8,m=0,!0}
function h(t,e){var i=[];if(e)for(var n=0;n255)throw"INVALID_CHARACTER_ERR: DOM Exception 5";return i},q.encode=function(t){if(1!=arguments.length)throw"SyntaxError: Not enough arguments";var e,i,n=q.PADCHAR,o=q.ALPHA,p=q.getbyte,r=[];t=""+t;var s=t.length-t.length%3;if(0==t.length)return t;for(e=0;s>e;e+=3)i=p(t,e)<<16|p(t,e+1)<<8|p(t,e+2),r.push(o.charAt(i>>18)),r.push(o.charAt(i>>12&63)),r.push(o.charAt(i>>6&63)),r.push(o.charAt(63&i));switch(t.length-s){case 1:i=p(t,e)<<16,r.push(o.charAt(i>>18)+o.charAt(i>>12&63)+n+n);break;case 2:i=p(t,e)<<16|p(t,e+1)<<8,r.push(o.charAt(i>>18)+o.charAt(i>>12&63)+o.charAt(i>>6&63)+n)}
return r.join("")},window.btoa||(window.btoa=q.encode)}
(window),$=window.$||{},$pt=window.$pt||{},$.Encryption=$pt.Encryption=function(){function t(t){return e(t)}
function e(t){return u(i(c(t),t.length*_))}
function i(t,e){t[e>>5]|=128<>>9<<4)+14]=e;for(var i=1732584193,n=-271733879,a=-1732584194,c=271733878,u=0;u>16)+(e>>16)+(i>>16);return n<<16|65535&i}
function a(t,e){return t<>>32-e}
function c(t){for(var e=Array(),i=(1<<_)-1,n=0;n>5]|=(t.charCodeAt(n/_)&i)<>2]>>n%4*8+4&15)+e.charAt(t[n>>2]>>n%4*8&15);return i}
function uin2hex(str){var maxLength=16;str=parseInt(str);for(var hex=str.toString(16),len=hex.length,i=len;maxLength>i;i++)hex="0"+hex;for(var arr=[],j=0;maxLength>j;j+=2)arr.push("\x"+hex.substr(j,2));var result=arr.join("");return eval('result="'+result+'"'),result;}
function g(t){for(var e=[],i=0;i 

Java文件

public interface JavascriptInterface {
    String getEncryption(String pwd, String user, String random);
}
import javax.script.Invocable;
import javax.script.scriptEngine;
import javax.script.scriptEngineManager;
import java.io.FileReader;
import java.io.IOException;


public class RSA {

    
    public static String encrpt(String pwd, String user, String random) {
        scriptEngine engine = new scriptEngineManager()
                .getEngineByName("Javascript");
        FileReader reader = null;
        try {
            reader = new FileReader(RSA.class.getClassLoader().getResource("en.js").getPath());
            engine.eval(reader);
            if (engine instanceof Invocable) {
                Invocable invocable = (Invocable) engine;
                JavascriptInterface executeMethod = invocable
                        .getInterface(JavascriptInterface.class);
                return executeMethod.getEncryption(pwd, user, random);
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

按照前端给的这套实现方式上线后,白天网站流量较小没什么问题,晚上平台流量变大后,运维很快发现服务器cpu负载飙升是平时的7倍左右,服务器随时可能宕机.然后开始加班优化
检查代码发现是*executeMethod.getEncryption(pwd, user, random)*这个方法执行很慢要5s左右,而这个接口又是一个高频请求的接口,因此这边堆积大量请求无法处理,拉胯整个服务器

然后上网查资料,最后找的 j2v8 据说很快,然后引入项目开始尝试集成

maven依赖
Linux版

 
            com.eclipsesource.j2v8
            j2v8_linux_x86_64
            3.1.6
        

windows与mac版

  V8执行JS本地测试使用对应平台版本
        
            com.eclipsesource.j2v8
            j2v8_macosx_x86_64
            4.6.0
        
        
            com.eclipsesource.j2v8
            j2v8_win32_x86_64
            4.6.0
        

首先js是一个不变的文件,因此把他放在类初始化加载可以节约时间,

 static {
        fileStr =  FileUtil.readString(new File(OrderLoginClientController.class.getClassLoader().getResource("encryption/en.js").getPath()),"UTF-8");
    }

然后调用V8类库函数,这方面资料不多,需要自己尝试V8里面的函数 ,runtime.executeJSFunction这个方法尝试后发现比之前快,但是还是要2秒左右,上线cpu负载还是很高,不能解决高并发下接口的可用,然后换成executeStringFunction这个函数,执行速度直接毫秒级别,不多说直接上生产,几分钟不到生产服务器的cpu降至平时正常水平10%左右,解决完问题已是凌晨,回家睡觉

  
    private String encrpt(String pwd, String user, String random) {
        V8 runtime = V8.createV8Runtime();
        V8Array v8Array = new V8Array(runtime);
        v8Array.push(pwd).push(user).push(random);
        try {
            runtime.executeVoidscript(fileStr);
           
            String getEncryption = runtime.executeStringFunction("getEncryption",v8Array);
            return getEncryption;
        }catch (Exception e){
            LOGGER.error("encrpt failed",e);
            LOGGER.info("encrpt failed");
        }finally {
            v8Array.release();
            runtime.release();
        }
        return null;
    }
总结

J2V8这方面资料网上很少也很不全,有的只是简单的场景,并不知道在高并发下的表现,因此找到合适的函数花费了不少时间,在此记录下

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/322173.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号