使用 Hibernate 存储统计数据
Store statistics with Hibernate
我有 AOP 方面来计算某些服务被调用的次数:
@Aspect
@Component
public class CounterAspect {
private Map<Integer, Integer> gettingEventStatistics = new HashMap<>();
@Pointcut("execution(Event EventService+.getById(Integer))")
private void gettingEvent() {}
@AfterReturning(pointcut = "gettingEvent()", returning = "retVal")
public void countGettingEvent(JoinPoint joinPoint, Object retVal) {
Integer id = (Integer) joinPoint.getArgs()[0];
if (id != null && retVal != null) {
Integer currentCounterValue = gettingEventStatistics.get(id);
gettingEventStatistics.put(id, currentCounterValue == null ? 1 : currentCounterValue + 1);
}
}
}
如何使用 Hibernate 将此类信息存储在数据库中?
最简单的方法是将其解析为 JSON 并存储为字符串。请记住增加列最大内存大小。
我制定了以下解决方案 - 为统计信息创建了实体
@Entity
public class GettingEventsStats {
@Id
private Integer eventId;
private Integer gettingCounter;
//getters, setters, etc.
在我的方面注入了 DAO 委托,具有这样的功能:
@Repository
public class HibernateStatsDao implements StatsDao {
@Autowired
private SessionFactory sessionFactory;
@Override
public GettingEventsStats getGettingEventStats(Integer eventId) {
return sessionFactory.getCurrentSession().get(GettingEventsStats.class, eventId);
}
@Override
public void createGettingEventCounter(Integer eventId) {
GettingEventsStats gettingEventsStats = new GettingEventsStats();
gettingEventsStats.setEventId(eventId);
gettingEventsStats.setGettingCounter(1);
sessionFactory.getCurrentSession().save(gettingEventsStats);
}
@Override
public void updateGettingEventCounter(Integer eventId) {
GettingEventsStats gettingEventStats = getGettingEventStats(eventId);
gettingEventStats.setGettingCounter(gettingEventStats.getGettingCounter() + 1);
sessionFactory.getCurrentSession().update(gettingEventStats);
}
}
并将方面逻辑更改为:
@Autowired
private StatsDao statsDao;
@Pointcut("execution(Event EventService+.getById(Integer))")
private void gettingEvent() {}
@AfterReturning(pointcut = "gettingEvent()", returning = "retVal")
public void countGettingEvent(JoinPoint joinPoint, Object retVal) {
Integer eventId = (Integer) joinPoint.getArgs()[0];
if (eventId != null && retVal != null) {
GettingEventsStats gettingEventStats = statsDao.getGettingEventStats(eventId);
if (gettingEventStats == null) {
statsDao.createGettingEventCounter(eventId);
} else {
statsDao.updateGettingEventCounter(eventId);
}
}
}
您将使用此方法保存大量条目。最好使用 Dropwizard Metrics,它使用 Reservoirs 进行数据采样和自定义报告器。
通常,指标最好通过 JMX 暴露给 APM 工具。或者您应该为此目的使用 Graphite 或 Graphana。
我有 AOP 方面来计算某些服务被调用的次数:
@Aspect
@Component
public class CounterAspect {
private Map<Integer, Integer> gettingEventStatistics = new HashMap<>();
@Pointcut("execution(Event EventService+.getById(Integer))")
private void gettingEvent() {}
@AfterReturning(pointcut = "gettingEvent()", returning = "retVal")
public void countGettingEvent(JoinPoint joinPoint, Object retVal) {
Integer id = (Integer) joinPoint.getArgs()[0];
if (id != null && retVal != null) {
Integer currentCounterValue = gettingEventStatistics.get(id);
gettingEventStatistics.put(id, currentCounterValue == null ? 1 : currentCounterValue + 1);
}
}
}
如何使用 Hibernate 将此类信息存储在数据库中?
最简单的方法是将其解析为 JSON 并存储为字符串。请记住增加列最大内存大小。
我制定了以下解决方案 - 为统计信息创建了实体
@Entity
public class GettingEventsStats {
@Id
private Integer eventId;
private Integer gettingCounter;
//getters, setters, etc.
在我的方面注入了 DAO 委托,具有这样的功能:
@Repository
public class HibernateStatsDao implements StatsDao {
@Autowired
private SessionFactory sessionFactory;
@Override
public GettingEventsStats getGettingEventStats(Integer eventId) {
return sessionFactory.getCurrentSession().get(GettingEventsStats.class, eventId);
}
@Override
public void createGettingEventCounter(Integer eventId) {
GettingEventsStats gettingEventsStats = new GettingEventsStats();
gettingEventsStats.setEventId(eventId);
gettingEventsStats.setGettingCounter(1);
sessionFactory.getCurrentSession().save(gettingEventsStats);
}
@Override
public void updateGettingEventCounter(Integer eventId) {
GettingEventsStats gettingEventStats = getGettingEventStats(eventId);
gettingEventStats.setGettingCounter(gettingEventStats.getGettingCounter() + 1);
sessionFactory.getCurrentSession().update(gettingEventStats);
}
}
并将方面逻辑更改为:
@Autowired
private StatsDao statsDao;
@Pointcut("execution(Event EventService+.getById(Integer))")
private void gettingEvent() {}
@AfterReturning(pointcut = "gettingEvent()", returning = "retVal")
public void countGettingEvent(JoinPoint joinPoint, Object retVal) {
Integer eventId = (Integer) joinPoint.getArgs()[0];
if (eventId != null && retVal != null) {
GettingEventsStats gettingEventStats = statsDao.getGettingEventStats(eventId);
if (gettingEventStats == null) {
statsDao.createGettingEventCounter(eventId);
} else {
statsDao.updateGettingEventCounter(eventId);
}
}
}
您将使用此方法保存大量条目。最好使用 Dropwizard Metrics,它使用 Reservoirs 进行数据采样和自定义报告器。
通常,指标最好通过 JMX 暴露给 APM 工具。或者您应该为此目的使用 Graphite 或 Graphana。