依赖性:
<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小组中的任何人是否可以对此进一步说明。