0

在发版的时候报错了;原先10台阿里云机器运行正常;

  1. 同样代码同样环境,系统发版,通过mongo发起读请求,有5台出现认证错误,5台正常;
  2. 接着代码回滚,配置回滚,但那5台机器还是继续报错;对比了代码、jar包等都是一致的。
  3. 怀疑是机器的问题,所以选择扩容新机器验证:
    1. 第一次扩容:从5台错误的机器中挑选出一台,克隆出5台新的机器(变成15台),其中新扩容的有2台是正常的,另外3台还是继续报认证异常;
    2. 第二次扩容:从没问题的机器里再克隆出4台新机器,全都正常。
  4. 写了个操作mongo的小程序放到有问题的节点上,没报错;
  5. 另外在本地通过debug可以复现,方式是让一个请求停留在某个断点较长时间,然后再运行时就会报错。

mongo客户端版本3.9.0;网上查了说jdk少了sun_provider.jar包什么的都对比过,不缺少;所有优点懵逼。

具体断点为:在ServiceList里停留一会,然后再运行,就会抛出Algorithm HmacSHA1 not available异常

Mac.getInstance(hmacAlgorithm);
GetInstance.getServices("Mac", var0);
var2.getServices(var0, var1)
return new ProviderList.ServiceList(var1, var2);
ServiceList(String var2, String var3) {
    this.type = var2;
    this.algorithm = var3;
    this.ids = null;
}

另外发现异常堆栈里,调用底层jdk时用的版本是javax.crypto.Mac.getInstance(Mac.java:181) ~[na:1.8.0_171],但是调用java线程池的是 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_172],版本不一致。

在跟踪底层源码时,异常最终是由JDK抛出;ScramShaAuthenticator.hi(“HmacSHA1”)->Mac.getInstance(“HmacSHA1”);

private byte[] hi(final byte[] password, final byte[] salt, final int iterations) throws SaslException {
    try {
        SecretKeySpec key = new SecretKeySpec(password, hmacAlgorithm);
        Mac mac = Mac.getInstance(hmacAlgorithm);
        mac.init(key);
        mac.update(salt);
        mac.update(INT_1);
        byte[] result = mac.doFinal();
        byte[] previous = null;
        for (int i = 1; i < iterations; i++) {
            mac.update(previous != null ? previous : result);
            previous = mac.doFinal();
            xorInPlace(result, previous);
        }
        return result;
    } catch (NoSuchAlgorithmException e) {
        throw new SaslException(format("Algorithm for '%s' could not be found.", hmacAlgorithm), e);
    } catch (InvalidKeyException e) {
        throw new SaslException(format("Invalid key for %s", hmacAlgorithm), e);
    }
}
public static final Mac getInstance(String var0) throws NoSuchAlgorithmException {
    List var1 = GetInstance.getServices("Mac", var0);
    Iterator var2 = var1.iterator();

    Service var3;
    do {
        if (!var2.hasNext()) {
            throw new NoSuchAlgorithmException("Algorithm " + var0 + " not available");
        }

        var3 = (Service)var2.next();
    } while(!JceSecurity.canUseProvider(var3.getProvider()));

    return new Mac(var3, var2, var0);
}

到现在还是没找出具体什么原因,请问有大佬知道这个是什么原因吗?

Exception authenticating MongoCredential{mechanism=SCRAMSHA1, userName=’****’, source=’****’, password=<hidden>, mechanismProperties={}} com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAMSHA1, userName=’****’, source=’****’, password=<hidden>, mechanismProperties={}} at com.mongodb.internal.connection.SaslAuthenticator.wrapException(SaslAuthenticator.java:173) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.SaslAuthenticator.access$300(SaslAuthenticator.java:40) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:70) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:47) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.SaslAuthenticator.doAsSubject(SaslAuthenticator.java:179) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:47) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.InternalStreamConnectionInitializer.authenticateAll(InternalStreamConnectionInitializer.java:151) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:64) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:127) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.UsageTrackingInternalConnection.open(UsageTrackingInternalConnection.java:50) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.open(DefaultConnectionPool.java:390) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:106) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:92) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.DefaultServer.getConnection(DefaultServer.java:85) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.getConnection(ClusterBinding.java:115) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:460) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:406) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.operation.FindOperation.execute(FindOperation.java:696) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.operation.FindOperation.execute(FindOperation.java:83) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:179) ~[mongodb-driver-3.9.0.jar!/:na] at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:132) ~[mongodb-driver-3.9.0.jar!/:na] at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:86) ~[mongodb-driver-3.9.0.jar!/:na] at

****

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_172] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_172] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_172] Caused by: javax.security.sasl.SaslException: Algorithm for ‘HmacSHA1’ could not be found. at com.mongodb.internal.connection.ScramShaAuthenticator$ScramShaSaslClient.hi(ScramShaAuthenticator.java:271) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.ScramShaAuthenticator$ScramShaSaslClient.getClientProof(ScramShaAuthenticator.java:205) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.ScramShaAuthenticator$ScramShaSaslClient.computeClientFinalMessage(ScramShaAuthenticator.java:182) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.ScramShaAuthenticator$ScramShaSaslClient.evaluateChallenge(ScramShaAuthenticator.java:121) ~[mongodb-driver-core-3.9.0.jar!/:na] at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:59) ~[mongodb-driver-core-3.9.0.jar!/:na] … 29 common frames omitted

Caused by: java.security.NoSuchAlgorithmException: Algorithm HmacSHA1 not available at javax.crypto.Mac.getInstance(Mac.java:181) ~[na:1.8.0_171] at com.mongodb.internal.connection.ScramShaAuthenticator$ScramShaSaslClient.hi(ScramShaAuthenticator.java:258) ~[mongodb-driver-core-3.9.0.jar!/:na] … 33 common frames omitted

更改状态以发布