问题描述
我想以 5/秒的速率向外部 API 发送请求,如下所示:
export default function CreateOrgan(props) {
/* Server State Handling */
const [serverState,setServerState] = useState();
const handleServerResponse = (ok,msg) => {
setServerState({ok,msg});
};
const handleOnSubmit = (values,actions) => {
axios({
method: "POST",url: "/organs",data: values
})
.then(response => {
props.history.push("/listorgan");
actions.setSubmitting(false);
actions.resetForm();
alert("Organ enregister avec succer");
})
.catch(error => {
actions.setSubmitting(false);
handleServerResponse(false,error.response.data.error);
});
};
return (
<PageWrapper>
<Formik
initialValues={{ id: "",nom: ""}}
onSubmit={handleOnSubmit}
validationSchema={formSchema}
>
{({ isSubmitting,values,errors,touched,isValidating,isValid
}) => (
<Form id="fs-frm" novalidate>
<Row>
<Col>
<Label htmlFor="code">
Code
<Input
type="text"
name="id"
autoCorrect="off"
autoComplete="name"
placeholder="Code"
valid={touched.id && !errors.id}
error={touched.id && errors.id}
/>
</Label>
{errors.id && touched.id && (
<StyledInlineErrorMessage>
{errors.id}
</StyledInlineErrorMessage>
)}
</Col>
<Col>
<Label htmlFor="code">
Nom
<Input
type="text"
name="nom"
autoCorrect="off"
autoComplete="name"
placeholder="Nom"
valid={touched.nom && !errors.nom}
error={touched.nom && errors.nom}
/>
</Label>
{errors.nom && touched.nom && (
<StyledInlineErrorMessage>
{errors.nom}
</StyledInlineErrorMessage>
)}
</Col>
</Row>
<Card.Footer style={{ "textAlign": "right" }}>
<button type="submit" className="btn btn-primary" disabled={isSubmitting} style={{ "width": "120px","margin": "1px","padding": "2px" }}>
Submit
</button>
</Card.Footer>
{serverState && (
<p className={!serverState.ok ? "errorMsg" : ""}>
{serverState.msg}
</p>
)}
</Form>
)}
</Formik>
</PageWrapper>
);
};
然后我将这个 rateLimiter 传递给方法(通过 for 调用):
//limit sending rate to 5 per second
RateLimiter rateLimiter = RateLimiter.create(5);
for(...){
broadcastToken = sendTemplateService.sendbroadcastPetition(broadcastInput,rateLimiter);
}
我的方法正确吗?我不希望整个方法每秒执行 5 次,我想要的是对 API 的调用最多为每秒 5 次。
这个 RateLimiter.create(5) 只会影响下一行?
解决方法
受到速率限制的是从 RateLimiter
对象获取许可。您已经创建了一个 RateLimiter
,每秒最多授予 5 个许可。因此,假设您只有一个 RateLimiter
,那么您每秒只能执行 rateLimiter.acquire()
5 次,因此您只能运行下一行调用 { {1}}也是每秒 5 次。
将 restTemplate.exchange
传递给函数使用它似乎有点奇怪,不过。哪个类负责确保 RateLimiter
每秒只被调用 5 次?如果它是 restTemplate.exchange
的类(无论它是什么),那么该类应该创建 sendBroadcastPetition
(或接受一个作为构造函数参数)并始终使用那个。现在的情况是,RateLimiter
的调用者可以通过每次传入不同的 sendBroadcastPetition
来突破速率限制。如果是调用者负责执行速率限制,则可以在调用 RateLimiter
之前调用 acquire
,并且不要传入 sendBroadcastPetition
。