java.net.SocketException:在AWS Lambda中异步添加Keen事件时,不允许操作(选择/轮询失败)

时间:2018-06-27 18:08:13

标签: java aws-lambda keen-io

依赖性:

<dependency>
    io.keen</groupId>
    keen-client-api-java</artifactId>
    5.2.0</
</dependency>

Bean创建:

@Bean
public KeenClient keenClient() {
    KeenClient keenClient = new JavaKeenClientBuilder().build();
    keenClient.setDefaultProject(new KeenProject(projectId, writeKey, readKey));
    keenClient.setDebugMode(debugMode);

    if (enableLogging) {
        KeenLogging.enableLogging();
    }

    return keenClient;
}

服务定义:

@Service
public class KeenAnalyticsService implements AnalyticsService {
    private static final Logger LOG = LoggerFactory.getLogger(KeenAnalyticsService.class);

    private final KeenClient keenClient;

    public static final String ID = "id";
    public static final String USER_LOGIN_EVENT = "user_login_event";

    @Autowired
    public KeenAnalyticsService(KeenClient keenClient) {
        this.keenClient = keenClient;
    }

    @Override
    public void submitUserLoginEvent(UserLoginAnalyticsEvent userLoginAnalyticsEvent) {
        Map<String, Object> event = Maps.newHashMap();
        event.put(USER_LOGIN_EVENT, userLoginAnalyticsEvent);
        addEvent(USER_LOGIN_EVENT, event);
    }

    private void addEvent(String collection, Map<String, Object> event) {
        addEvent(collection, event, Maps.newHashMap());
    }

    private void addEvent(String collection, Map<String, Object> event, Map<String, Object> keenProperties) {
        if (!event.containsKey(ID)) {
            String id = UUID.randomUUID().toString();
            LOG.info("Adding {} Keen event with ID ({})", collection, id);
            event.put(ID, id);
        } else {
            LOG.info("Adding {} Keen event with existing ID ({})", collection, event.get(ID));
        }

            try {
            keenClient.addEventAsync(keenClient.getDefaultProject(), collection, event, keenProperties, new LoggingKeenCallback());
        } catch (Throwable e) {
            LOG.warn("Unable to add event", e);
        }
    }

    private static class LoggingKeenCallback implements KeenDetailedCallback {
        @Override
        public void onSuccess() {}

        @Override
        public void onFailure(Exception e) {}

        @Override
        public void onSuccess(KeenProject project, String eventCollection, Map<String, Object> event, Map<String, Object>     keenProperties) {
            LOG.info("Successfully processed event asynchronously with ID({}) to Collection({})", event.get(ID),     eventCollection);
        }

        @Override
        public void onFailure(KeenProject project, String eventCollection, Map<String, Object> event, Map<String, Object>     keenProperties, Exception e) {
            LOG.warn("Unable to process event asynchronously with ID({}) to Collection({})", event.get(ID), eventCollection,     e);
        }
    }

}

我正在获取以下堆栈跟踪:

Exception in thread "pool-1-thread-1" java.lang.RuntimeException: java.net.SocketException: Operation not permitted (select/    poll failed)
    at io.keen.client.java.KeenClient.handleFailure(KeenClient.java:1643)
    at io.keen.client.java.KeenClient.addEvent(KeenClient.java:171)
    at io.keen.client.java.KeenClient$1.run(KeenClient.java:243)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketException: Operation not permitted (select/poll failed)
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
    at sun.security.ssl.InputRecord.read(InputRecord.java:503)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1316)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1291)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
    at io.keen.client.java.http.UrlConnectionHttpHandler.sendRequest(UrlConnectionHttpHandler.java:86)
    at io.keen.client.java.http.UrlConnectionHttpHandler.execute(UrlConnectionHttpHandler.java:30)
    at io.keen.client.java.KeenClient.publishObject(KeenClient.java:1436)
    at io.keen.client.java.KeenClient.publish(KeenClient.java:1370)
    at io.keen.client.java.KeenClient.addEvent(KeenClient.java:168)
    ... 4 more

对于可能导致此问题的原因是否有任何想法?当我以同步方式而不是异步方式添加事件时,问题就消失了,但是如果可能的话,我宁愿添加事件异步。

我有99%的把握确保这是Lambda在执行过程中中断执行的活动,但我想确定。我个人不认识stacktrace,因此我只能从中推测出很多东西。

很明显,我不想延迟用户登录尝试的次数,但是如果我作为最后一件事异步异步触发敏锐事件,然后再将登录结果返回给用户,那肯定是某种与容器关闭和发送敏锐事件有关的时间问题。

然后,Lambda可能足够聪明,可以等待子派生线程完成。再说一次,可能不会。当主线程按设计完成执行后,它可能会退出。

好奇基恩小组或Lambda小组中的任何人是否可以对此进一步说明。

0 个答案:

没有答案
相关问题