use of com.google.common.util.concurrent.RateLimiter in project new-cloud by xie-summer.
the class ServiceRateLimitZuulFilter method run.
@Override
public Object run() {
try {
RequestContext context = RequestContext.getCurrentContext();
HttpServletResponse response = context.getResponse();
String key = null;
// 对于service格式的路由,走RibbonRoutingFilter
String serviceId = (String) context.get(SERVICE_ID_KEY);
if (serviceId != null) {
key = serviceId;
map.putIfAbsent(serviceId, RateLimiter.create(1000.0));
} else // 如果压根不走RibbonRoutingFilter,则认为是URL格式的路由
{
// 对于URL格式的路由,走SimpleHostRoutingFilter
URL routeHost = context.getRouteHost();
if (routeHost != null) {
String url = routeHost.toString();
key = url;
map.putIfAbsent(url, RateLimiter.create(2000.0));
}
}
RateLimiter rateLimiter = map.get(key);
if (!rateLimiter.tryAcquire()) {
HttpStatus httpStatus = HttpStatus.TOO_MANY_REQUESTS;
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
response.setStatus(httpStatus.value());
response.getWriter().append(httpStatus.getReasonPhrase());
context.setSendZuulResponse(false);
throw new RateLimiterException(httpStatus.getReasonPhrase(), httpStatus.value(), httpStatus.getReasonPhrase());
}
} catch (Exception e) {
ReflectionUtils.rethrowRuntimeException(e);
}
return null;
}
use of com.google.common.util.concurrent.RateLimiter in project bookkeeper by apache.
the class UpdateLedgerOp method updateBookieIdInLedgers.
/**
* Update the bookie id present in the ledger metadata.
*
* @param oldBookieId
* current bookie id
* @param newBookieId
* new bookie id
* @param rate
* number of ledgers updating per second (default 5 per sec)
* @param limit
* maximum number of ledgers to update (default: no limit). Stop
* update if reaching limit
* @param progressable
* report progress of the ledger updates
* @throws IOException
* if there is an error when updating bookie id in ledger
* metadata
* @throws InterruptedException
* interrupted exception when update ledger meta
*/
public void updateBookieIdInLedgers(final BookieSocketAddress oldBookieId, final BookieSocketAddress newBookieId, final int rate, final int limit, final UpdateLedgerNotifier progressable) throws IOException {
final ExecutorService executor = Executors.newSingleThreadExecutor(new DefaultThreadFactory("UpdateLedgerThread", true));
final AtomicInteger issuedLedgerCnt = new AtomicInteger();
final AtomicInteger updatedLedgerCnt = new AtomicInteger();
final Future<?> updateBookieCb = executor.submit(new Runnable() {
@Override
public void run() {
updateLedgers(oldBookieId, newBookieId, rate, limit, progressable);
}
private void updateLedgers(final BookieSocketAddress oldBookieId, final BookieSocketAddress newBookieId, final int rate, final int limit, final UpdateLedgerNotifier progressable) {
try {
final AtomicBoolean stop = new AtomicBoolean(false);
final Set<Long> outstandings = Collections.newSetFromMap(new ConcurrentHashMap<Long, Boolean>());
final RateLimiter throttler = RateLimiter.create(rate);
final Iterator<Long> ledgerItr = admin.listLedgers().iterator();
final CountDownLatch syncObj = new CountDownLatch(1);
// iterate through all the ledgers
while (ledgerItr.hasNext() && !stop.get()) {
// throttler to control updates per second
throttler.acquire();
final Long lId = ledgerItr.next();
final ReadLedgerMetadataCb readCb = new ReadLedgerMetadataCb(bkc, lId, oldBookieId, newBookieId);
outstandings.add(lId);
FutureCallback<Void> updateLedgerCb = new UpdateLedgerCb(lId, stop, issuedLedgerCnt, updatedLedgerCnt, outstandings, syncObj, progressable);
Futures.addCallback(readCb.getFutureListener(), updateLedgerCb);
issuedLedgerCnt.incrementAndGet();
if (limit != Integer.MIN_VALUE && issuedLedgerCnt.get() >= limit || !ledgerItr.hasNext()) {
stop.set(true);
}
bkc.getLedgerManager().readLedgerMetadata(lId, readCb);
}
// waiting till all the issued ledgers are finished
syncObj.await();
} catch (IOException ioe) {
LOG.error("Exception while updating ledger", ioe);
throw new RuntimeException("Exception while updating ledger", ioe.getCause());
} catch (InterruptedException ie) {
LOG.error("Exception while updating ledger metadata", ie);
Thread.currentThread().interrupt();
throw new RuntimeException("Exception while updating ledger", ie.getCause());
}
}
});
try {
// Wait to finish the issued ledgers.
updateBookieCb.get();
} catch (ExecutionException ee) {
throw new IOException("Exception while updating ledger", ee);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new IOException("Exception while updating ledger", ie);
} finally {
executor.shutdown();
}
}
use of com.google.common.util.concurrent.RateLimiter in project web3sdk by FISCO-BCOS.
the class Perfomance method main.
public static void main(String[] args) throws Exception {
if (args.length < 6) {
System.out.println("参数: 请求方 接收方 总请求量 发送TPS 包大小 超时时间");
return;
}
String from = args[0];
String to = args[1];
Integer count = Integer.parseInt(args[2]);
Integer tps = Integer.parseInt(args[3]);
Integer packageSize = Integer.parseInt(args[4]);
Integer timeout = Integer.parseInt(args[5]);
logger.debug("初始化");
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Service service = context.getBean(Service.class);
service.setPushCallback(new PushCallback());
service.run();
System.out.println("3s后开始测试...");
Thread.sleep(1000);
System.out.println("2s后开始测试...");
Thread.sleep(1000);
System.out.println("1s后开始测试...");
Thread.sleep(1000);
System.out.println("开始测试");
System.out.println("===================================================================");
ChannelRequest request = new ChannelRequest();
request.setAppName("");
request.setBankNO("");
request.setFromOrg(from);
request.setOrgApp("");
request.setTimeout(0);
request.setToOrg(to);
request.setTimeout(timeout);
request.setVersion("");
String message = "";
for (Integer i = 0; i < packageSize; ++i) {
message += "z";
}
Map<Integer, RequestTimer> resultMap = new ConcurrentHashMap<Integer, RequestTimer>();
PerfomanceCollector collector = new PerfomanceCollector();
collector.total = count;
collector.resultMap = resultMap;
collector.startTimestamp = System.currentTimeMillis();
collector.tps = tps;
collector.packageSize = packageSize;
RateLimiter limiter = RateLimiter.create((double) tps);
for (Integer seq = 0; seq < count; ++seq) {
limiter.acquire();
if ((seq + 1) % (count / 10) == 0) {
System.out.println("已发送:" + String.valueOf((seq + 1) * 100 / count) + "%");
}
request.setContent(message);
request.setMessageID(service.newSeq());
RequestTimer timer = new RequestTimer();
timer.sendTimestamp = System.currentTimeMillis();
resultMap.put(seq, timer);
PerfomanceCallback callback = new PerfomanceCallback();
callback.collector = collector;
service.asyncSendChannelMessage(request, callback);
}
System.out.println("共发送:" + String.valueOf(count) + "条");
}
use of com.google.common.util.concurrent.RateLimiter in project bookkeeper by apache.
the class SearchReplaceBookieIdCommand method run.
@Override
protected void run(BookKeeper bk, Flags flags) throws Exception {
try (BookKeeperAdmin admin = new BookKeeperAdmin((org.apache.bookkeeper.client.BookKeeper) bk)) {
LedgerManager ledgerManager = ((org.apache.bookkeeper.client.BookKeeper) bk).getLedgerManager();
long i = 0;
BookieId fromAddr = BookieId.parse(flags.from);
BookieId toAddr = BookieId.parse(flags.to);
System.out.println(String.format("Replacing bookie id %s with %s in metadata", fromAddr, toAddr));
RateLimiter limiter = RateLimiter.create(flags.rate);
for (Long lid : admin.listLedgers()) {
Versioned<LedgerMetadata> md = ledgerManager.readLedgerMetadata(lid).get();
if (md.getValue().getAllEnsembles().entrySet().stream().anyMatch(e -> e.getValue().contains(fromAddr))) {
limiter.acquire();
LedgerMetadataBuilder builder = LedgerMetadataBuilder.from(md.getValue());
md.getValue().getAllEnsembles().entrySet().stream().filter(e -> e.getValue().contains(fromAddr)).forEach(e -> {
List<BookieId> ensemble = new ArrayList<>(e.getValue());
ensemble.replaceAll((a) -> {
if (a.equals(fromAddr)) {
return toAddr;
} else {
return a;
}
});
builder.replaceEnsembleEntry(e.getKey(), ensemble);
});
LedgerMetadata newMeta = builder.build();
if (flags.verbose) {
System.out.println("Replacing ledger " + lid + " metadata ...");
System.out.println(md.getValue().toSafeString());
System.out.println("with ...");
System.out.println(newMeta.toSafeString());
}
i++;
if (!flags.dryRun) {
ledgerManager.writeLedgerMetadata(lid, newMeta, md.getVersion()).get();
}
}
if (i >= flags.max) {
System.out.println("Max number of ledgers processed, exiting");
break;
}
}
System.out.println("Replaced bookie ID in " + i + " ledgers");
}
}
use of com.google.common.util.concurrent.RateLimiter in project bookkeeper by apache.
the class UpdateLedgerOp method updateBookieIdInLedgers.
/**
* Update the bookie id present in the ledger metadata.
*
* @param oldBookieId
* current bookie id
* @param newBookieId
* new bookie id
* @param rate
* number of ledgers updating per second (default 5 per sec)
* @param limit
* maximum number of ledgers to update (default: no limit). Stop
* update if reaching limit
* @param progressable
* report progress of the ledger updates
* @throws IOException
* if there is an error when updating bookie id in ledger
* metadata
*/
public void updateBookieIdInLedgers(final BookieId oldBookieId, final BookieId newBookieId, final int rate, int maxOutstandingReads, final int limit, final UpdateLedgerNotifier progressable) throws IOException, InterruptedException {
final AtomicInteger issuedLedgerCnt = new AtomicInteger();
final AtomicInteger updatedLedgerCnt = new AtomicInteger();
final CompletableFuture<Void> finalPromise = new CompletableFuture<>();
final Set<CompletableFuture<?>> outstanding = Collections.newSetFromMap(new ConcurrentHashMap<CompletableFuture<?>, Boolean>());
final RateLimiter throttler = RateLimiter.create(rate);
final Semaphore outstandingReads = new Semaphore(maxOutstandingReads);
final Iterator<Long> ledgerItr = admin.listLedgers().iterator();
// iterate through all the ledgers
while (ledgerItr.hasNext() && !finalPromise.isDone() && (limit == Integer.MIN_VALUE || issuedLedgerCnt.get() < limit)) {
// semaphore to control reads according to update throttling
outstandingReads.acquire();
final long ledgerId = ledgerItr.next();
issuedLedgerCnt.incrementAndGet();
CompletableFuture<Versioned<LedgerMetadata>> writePromise = lm.readLedgerMetadata(ledgerId).thenCompose((readMetadata) -> {
AtomicReference<Versioned<LedgerMetadata>> ref = new AtomicReference<>(readMetadata);
return new MetadataUpdateLoop(lm, ledgerId, ref::get, (metadata) -> {
return metadata.getAllEnsembles().values().stream().flatMap(Collection::stream).anyMatch(b -> b.equals(oldBookieId));
}, (metadata) -> {
return replaceBookieInEnsembles(metadata, oldBookieId, newBookieId);
}, ref::compareAndSet, throttler).run();
});
outstanding.add(writePromise);
writePromise.whenComplete((metadata, ex) -> {
if (ex != null && !(ex instanceof BKException.BKNoSuchLedgerExistsOnMetadataServerException)) {
String error = String.format("Failed to update ledger metadata %s, replacing %s with %s", ledgerId, oldBookieId, newBookieId);
LOG.error(error, ex);
finalPromise.completeExceptionally(new IOException(error, ex));
} else {
LOG.info("Updated ledger {} metadata, replacing {} with {}", ledgerId, oldBookieId, newBookieId);
updatedLedgerCnt.incrementAndGet();
progressable.progress(updatedLedgerCnt.get(), issuedLedgerCnt.get());
}
outstandingReads.release();
outstanding.remove(writePromise);
});
}
CompletableFuture.allOf(outstanding.stream().toArray(CompletableFuture[]::new)).whenComplete((res, ex) -> {
if (ex != null) {
finalPromise.completeExceptionally(ex);
} else {
finalPromise.complete(null);
}
});
try {
finalPromise.get();
LOG.info("Total number of ledgers issued={} updated={}", issuedLedgerCnt.get(), updatedLedgerCnt.get());
} catch (ExecutionException e) {
String error = String.format("Error waiting for ledger metadata updates to complete (replacing %s with %s)", oldBookieId, newBookieId);
LOG.info(error, e);
if (e.getCause() instanceof IOException) {
throw (IOException) e.getCause();
} else {
throw new IOException(error, e);
}
}
}
Aggregations